堆排序 js實現

/* 最近 在看c語言版的數據結構,c用法着實很難,因而按照意思,仿照c語言寫了javascript版的三種排序方法!僅供你們一塊兒學習和參考
   後續比較難的歸併排序,和快速排序,之後再說 ,廢話不說,直接邊代碼邊講解!*/
<script type="text/javascript"> 
   var a=[0,9,8,7,6,5,4,3,2,1];
   
   
   /*希爾排序,
   將表分爲幾段長度,分別進行排序,而後進行總的排序*/
   function shellSort(t)
   {
       var i,j,temp;
       var increment=t.length;
       do
       { 
         //取到希爾跳躍 由於js取到的是浮點數,咱們要把它轉化成不大於該值得整數
           increment=Math.floor(increment/3+1);
           for(i=increment;i<t.length;i++)//循環便利increment到t.length的值
           {
               if(t[i]<t[i-increment]){//前面值大於後面值 則將t[i]插入有序增量子表
                   temp=t[i];//先將小的數值存儲
                   for(j=i-increment;j>=0&&temp<t[j];j-=increment){//跳值便利前面的數值,將比找到的這個小的值大的值日後移
                         t[j+increment]=t[j];//不斷移動,找到這個temp應該插入的位置
                          }
                 t[j+increment]=temp;//插入該位置!
                   }
               }
           }
       while(increment>1)
   }
   
   /*
   js版插入排序
   形如咱們打撲克同樣,先取到的撲克牌(數字)做爲標準,而後拿到下一個撲克牌(數字),比對前面的數字,將它插入到比前面的撲克牌大,
   比後面的數值小的位置,由於前面已是有序的,只須要從後往前遍歷,把比它大的順序後移一位,空出位置,插到空位
   */
   function insert(l){
       var temp,len=l.length;
       for(var i=1;i<len;i++){//以第一個爲基準,遍歷之後的進行插入
           if(l[i]<l[i-1]){//噹噹前數字 小於前一個,就把前面的數字比當前l[j]大的向後移動移動一位;空出最後一個比l[j]大的位置
               temp=l[i];
               for(var j=i-1;j>=0&&l[j]>temp;j--){
                   l[j+1]=l[j];
                   }
                   l[j+1]=temp;//插到正確位置!此時j指針又向後移動了一位,才跳出循環,因此須要j+1;
               }
           }
       }
       /*
       堆排序:原理是,將數組當作一個徹底二叉樹;
       形如:     0
             1      2
           3   4  5   6
        7   8 9 10
       只須要遍歷一半的值,進行循環比對,把最大的節點賦值到根的位置,而後把根部的值和最後一個數值交換,排除最後一個數值
       繼續打造大頂堆,最終造成一個小頂堆的算法!
       構造堆排序 s爲最小值,m爲最大值
       */
       function HeapAdjust(l,s,m){//使用調整大頂堆進行排序,將s到m之間的數值調整爲大頂堆!
           var temp=l[s];//將大頂堆頂值負值給temp;
           for(var j=2*s+1;j<m;j=2*j+1)//因爲下標是0;這裏只從0,1,3,5...每列的第一個數字開始便利就行
           {
               if(j<m&&l[j]<l[j+1])//若是當前下標的值比下一個下標的數值比下一個小(咱們是要找最大的那個),則就使j+1指向那個數字
                   ++j;
               if(temp>=l[j])//若是堆頂的值大於當前j下標的值,就不用再找了。跳出循環
                 break;
               l[s]=l[j];//小於j下標的值,就把l[j]複製給l[s]
               s=j;//s就指向當前j的位置,爲下步把頂值賦值到這個位置作準備(循環完以前,先不賦值)
               }
              l[s]=temp;//最後賦值給l[s](s指向如今找到的最大的大堆頂的值)
           }
       function HeapSort(l)
       {
           for(var i=l.length/2;i>=0;i--)//首先構造一個標準的大堆頂,只須要便利二叉樹一半的節點,就可以把大堆頂構造出來
               HeapAdjust(l,i,l.length);
           for(var i=l.length;i>0;i--){//構造完以後 把堆頂的值和最後一個互換,而後 排除最後一個繼續進行打造大堆頂!
               swap(l,0,i-1);
               HeapAdjust(l,0,i-2);
           }
       }
       function swap(l,i,j){
           var temp=l[i];
           l[i]=l[j];
           l[j]=temp;
       }
      shellSort(a);
       //insert(a);
   console.log(a);
</script>
相關文章
相關標籤/搜索