堆排序 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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM