1. 程式人生 > 實用技巧 >基於Vue.js PC桌面端彈出框元件|vue自定義彈層元件|vue模態框

基於Vue.js PC桌面端彈出框元件|vue自定義彈層元件|vue模態框

堆排序基本介紹

1) 堆排序是利用堆(heap)這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序,它的最壞,最好,平均時間複雜度均為 O(nlogn),它也是不穩定排序

堆排序的基本思想是:

1. 將待排序序列構造成一個大(小)頂堆
2. 此時,整個序列的最大(小)值就是堆頂的根節點。
3. 將其與末尾元素進行交換,此時末尾就為最大(小)值。
4. 然後將剩餘n-1個元素重新構造成一個堆,這樣會得到n個元素的次小(大)值。如此反覆執行,便能得到一個有序序列了。

堆的介紹

1. 必須是完全二叉樹
2. 每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆
3. 每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆


注意 : 沒有求結點的左孩子的值和右孩子的值的大小關係,一般升序採用大頂堆,降序採用小頂堆

大頂堆:

小頂堆:

堆排序步驟圖解

步驟一
構造初始堆。將給定無序序列構造成一個大頂堆(一般升序採用大頂堆,降序採用小頂堆)。

原始的陣列 [4, 6, 8, 5, 9]

1) .假設給定無序序列結構如下


2) .此時我們從最後一個非葉子結點開始(葉結點自然不用調整,第一個非葉子結點arr.length/2-1=5/2-1=1,也就是下面的 6 結點),從右至左,從下至上進行調整。

3) .找到第二個非葉節點 4,由於[4,9,8]中 9 元素最大,4 和 9 交換。

4) 這時,交換導致了子根[4,5,6]結構混亂,繼續調整(通過遞迴方法完成),[4,5,6]中 6 最大,交換 4 和 6。

此時,我們就將一個無序序列構造成了一個大頂堆。

步驟二 將堆頂元素與末尾元素進行交換,使末尾元素最大。然後繼續調整堆,再將堆頂元素與末尾元素交換
得到第二大元素。如此反覆進行交換、重建、交換。

1) .將堆頂元素 9 和末尾元素 4 進行交換

2) .重新調整結構,使其繼續滿足堆定義

3) .再將堆頂元素 8 與末尾元素 5 進行交換,得到第二大元素 8.

4) 後續過程,繼續進行調整,交換,如此反覆進行,最終使得整個序列有序

程式碼實現

1. //要求將陣列進行升序排序
2. publicclassHeapSort{
3. publicstaticvoidmain(String[]args){
4. int[]arr={11,100,108,-17,125,13,114,21}; 5. 6. heapSort(arr,arr.length); 7. 8. for(intdata:arr){ 9. System.out.println(data); 10. } 11. } 12. 13. /** 14. *@paramarr要變成堆的陣列 15. *@paramlen陣列的長度 16. *@parami對哪一個節點進行堆化 17. *@TODO將某棵完全二叉樹進行堆化操作 18. */ 19. publicstaticvoidheapify(int[]arr,intlen,inti){ 20. if(i>=len){//遞迴結束條件 21. return; 22. } 23. intleft=i*2+1;//i結點的左子結點 24. intright=i*2+2;//i結點的右子結點 25. intmax=i;//預設令下標為i的結點為最大值 26. if(left<len&&arr[left]>arr[max]){//找到當前二叉樹左子結點與該節點的較大值 27. max=left; 28. } 29. if(right<len&&arr[right]>arr[max]){//將上面比較出的較大值與該節點的右子結點比較獲取最大值 30. max=right; 31. } 32. if(max!=i){//如果max不等於i,說明i結點不是最大值,因此就需要將i結點值與最大值的結點進行交換 33. inttemp=arr[max]; 34. arr[max]=arr[i]; 35. arr[i]=temp; 36. /*交換完成後,就可以保證i結點的二叉樹是堆化的, 37. 但不能保證左右子結點的子樹(i的左右子結點為父節點時) 38. 是否也是堆化因此需要遞迴操作進行之後的堆化*/ 39. heapify(arr,len,max); 40. 41. } 42. } 43. 44. /** 45. *通過此方法就可將整棵樹進行堆化 46. *流程:從最後一個父節點(注意不是葉子節點)開始進行堆化,直到根節點 47. * 48. *@paramarr 49. *@paramlen 50. */ 51. publicstaticvoidbuildHeap(int[]arr,intlen){ 52. intlastNode=len-1;//最後一個葉子節點 53. inti=(lastNode-1)/2;//最後一個結點的父節點,即最後一個父結點 54. for(intj=i;j>=0;j--){//從最後一個父節點開始進行堆化,直到根節點(j==0) 55. heapify(arr,len,j); 56. } 57. } 58. 59. /** 60. *此方法能夠將陣列進行堆排序(有序(列)化) 61. * 62. *@paramarr要排序的陣列 63. *@paramlen要排序的陣列長度 64. */ 65. privatestaticvoidheapSort(int[]arr,intlen){ 66. buildHeap(arr,len);//首先通過此方法將其堆化,變為大頂堆(arr[0]為樹中最大值) 67. for(inti=len-1;i>0;i--){//從最後一個節點開始,i可以不用等於0,因為最後一個數一定是有序的 68. inttemp=arr[i]; 69. arr[i]=arr[0]; 70. arr[0]=temp;//將arr[0]與arr[i]進行交換,arr[i]之後都是確定有序的 71. heapify(arr,i,0);//交換完成後,又不是大頂堆規則了,需要再次堆化,找到次大值。注意現在在0到i之中找出最大值 72. } 73. } 74. 75. }