堆排序和建立最大堆


堆是完全二叉樹的結構,因此對於一個有n個節點的堆,高度為O(logn)。

最大堆:堆中的最大元素存放在根節點的位置。

           除了根節點,其他每個節點的值最多與其父節點的值一樣大。也就是任意一個子樹中包含的所有節點的值都不大於樹根節點的值。

堆中節點的位置編號都是確定的,根節點編號為1,每一層從左到右依次編號。由堆是完全二叉樹,可以知道當堆中某個節點的編號為i時,如果這個節點有左右子樹,那么左子樹的節點編號為2*i,右子樹的節點編號為2*i+1(當然這是在根節點編號為1的情況時)。

並且有n個節點的堆中葉子節點的編號為從n/2+1~n。因為假設節點n/2+1不是葉子節點,那么它的左子節點編號(n/2+1)*2=n+1,而節點總共只有n個。完全二叉樹的葉子節點只出現在最下面兩層。最下層的葉子集中在左邊,倒數二層的葉子集中在右邊。

維護最大堆函數MAX_HEAPWEIHU(A,i),假定節點i的左右子樹已經是最大堆。那么維護堆時,先比較i節點的值與左右節點值的大小,將三個數中的最大值交換到根節點的位置。假設根節點i與左子節點的值交換了,那么左子樹就要再次調用MAX_HEAPWEIHU(A,2*i),判斷左子樹還是不是最大堆,如果是則結束,否則繼續調用進行維護。因此調用MAX_HEAPWEIHU(A,i)的時間復雜度為O(logn)。

void heapfy(int a[],int i,int heapsize)
{
     int largest=i;
     int left=2*i+1;
     int right=left+1;
     if(left<heapsize && a[i]<a[left])  
           largest=left;
     if(right<heapsize && a[largest]<a[right])
           largest=right;
     if(largest!=i)
     {
           swap(a[i],a[largest]);
           heapfy(a,largest);
     }
}

建立最大堆:將A[1,n]數組轉換為最大堆。因為最大堆為完全二叉樹結構,因此A[n/2+1],……,A[n]是最大堆的葉子節點。每個葉子節點本身就是一個最大堆,所以我們就要從A[n/2]~A[1]逐步維護這個最底層的最大堆(調用MAX_HEAPWEIHU(A,i)維護)。

void buildheap(int a[],int len)
{
      for(int i=len/2-1;i>=0;i--)
          heapfy(a,i,len);
}        

堆排序:先建立一個最大堆。然后將最大堆的A[1]與A[n]交換,然后從堆中去掉這個節點n,通過減少A.heap_size的值來實現。剩余的節點中,新的根節點可能違背了最大堆的性質,因此需要調用MAX_HEAPWEIHU(A,1)來維護最大堆。

void sortheap(int a[],int len)
{
   
    for(int i=n-1;i>=0;i--)
    {
         swap(a[0],a[i]);
         heapfy(a,0,i);
    }
}    
#include<iostream>
using namespace std;
void heapfy(int a[],int index,int heapsize)
{
    int left=index*2+1;
    int right=left+1;
    int largest=index;
    if(left<heapsize&&a[index]<a[left])
        largest=left;
    if(right<heapsize&&a[largest]<a[right])
        largest=right;
    if(largest!=index)
    {
        swap(a[index],a[largest]);
        heapfy(a,largest,heapsize);
    }
}
void heapsort(int a[],int len)
{
    for(int i=len/2-1;i>=0;i--)
    {
        heapfy(a,i,len);
    }
    for(int i=len-1;i>=0;i--)
    {
        swap(a[i],a[0]);
        heapfy(a,0,i);
    }
}
int main()
{
    int a[10]={9,3,4,5,1,8,0,2,7,6};
    heapsort(a,10);    
}

 


免責聲明!

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



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