日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

堆排序(基于完全二叉树)

發布時間:2025/3/15 编程问答 11 豆豆
生活随笔 收集整理的這篇文章主要介紹了 堆排序(基于完全二叉树) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.堆排序是利用堆這種數據結構而設計的一種排序算法,堆排序是一種選擇排序,它的 最壞,最好,平均時間復雜度均為O(nlogn),它也是不穩定排序。 2.堆是具有以下性質的完全二叉樹:每個結點的值都大于或等于其左右孩子結點的值, 稱為大頂堆,注意:沒有要求結點的左孩子的值和右孩子的值的大小關系。 3.每個結點的值都小于或等于其左右孩子結點的值,稱為小頂堆

堆排序的的關鍵就是構建初始堆(大頂堆(升序)和小頂堆(降序)):
首先先明確,在一棵完全二叉樹中,有以下規律:

如果某個結點的下標為i,則: 其父節點下標為:parent=(i-1)/2 其左子結點的下標為:c1=2i+1 其右子結點的下標為:c2=2i+2

下圖所示的樹在數組中的存儲為:arr=[53,17,78,09,45,65,87,32]

其構建大頂堆的過程:選擇最后的葉子結點所在的父節點作為初始結點(上圖為09結點,因為最后一個葉結點的下標是int lastNode=n-1;,所以其父結點(09)下標=int parent=(lastNode-1)/2;),然后,將此父節點與其左右字節點進行比較,最大的作為新的父結點,如此便完成某棵子樹的大頂堆化。然后自下往上,以右往左(上圖次序:09,78,17,53)對每一棵子樹進行大頂堆化,直到根結點。注意:如果在大頂堆化的過程中,破壞了原來的樹的結構的話,還要繼續再向下大頂堆化,如上黑字。
小頂堆化以此類推

代碼實現(java):

public class heapSort {public static void main(String[] args) {int[] tree = {53, 17, 78, 9, 45, 65, 87, 32, 34, 42, 66, 89, 76, 199, 345, 213, 4, 6, 35};Sort sort = new Sort(tree);sort.sortHeap(tree,tree.length);for (int value : tree) {System.out.println(value);}} } class Sort{int []tree;public Sort(int[] tree) {this.tree=tree;}public void swap(int[] arr, int i, int j){int temp=arr[i];arr[i]=arr[j];arr[j]=temp;}//構建大頂堆函數public void buildHeap(){int lastNode=tree.length-1;//循環建造各子樹的大頂堆,父結點下標從(lastNode-1)/2遞減for (int parent=(lastNode-1)/2;parent>=0;parent--){heapify(tree,tree.length,parent);}}//找出某棵子樹的最大值,移到父結點//n代表這個樹里有多少個結點//i代表對下標是幾的結點進行大頂堆化//注意,這里的tree會隨著遞歸變化的public void heapify(int[] tree, int n, int i) {if(i>=n){return;}//設置當前的最大值為父結點,然后再進行比較int max = i;int leftChild = 2 * i + 1;int rightChild = 2 * i + 2;//leftChild<n為了保證不越界if (leftChild<n && tree[leftChild] > tree[i]) {//再比較兩個子節點的大小if(rightChild<n && tree[leftChild]>tree[rightChild]){max = leftChild;}}if (rightChild<n && tree[rightChild] > tree[i]){if(tree[leftChild]<tree[rightChild]){max=rightChild;}}//如果最大值下標發生改變,則交換if(max!=i){swap(tree,max,i);//遞歸完成堆化,此遞歸防止大頂堆化的過程中,破壞了原來樹的結構,所以要向下大頂堆化heapify(tree,n,max);}}public void sortHeap(int[]tree,int n){//構建大頂堆buildHeap();//for(int i=n-1;i>=0;i--){//交換根結點(最大值)和最后一個葉子結點swap(tree,i,0);//這里只要從根結點開始heapify就好,因為之前已經在buildHeap()中把下面的子樹都構建成大頂堆了,i=n-1表示每次都砍斷最后一個結點heapify(tree,i,0);}} }

動態演示:

總結

以上是生活随笔為你收集整理的堆排序(基于完全二叉树)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。