/* 最近 在看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>