1、堆排序演算法描寫敘述:
(1)定義
n個keyword序列kl,k2,…,kn稱為(heap)。當且僅當該序列滿足例如以下性質(簡稱為堆性質):
1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n/2)。當然。這是小根堆。大根堆則換成》=號。//k(i)相當於
二叉樹的非
葉子結點,k(2i)則是左子節點。k(2i+1)是右子節點
2)若將此序列所儲存的向量r[1..n]看做是一棵全然二叉樹的
儲存結構
,則堆實質上是滿足例如以下性質的全然二叉樹:
樹中任一非葉子結點的keyword均不大於(或不小於)其左右孩子(若存在)結點的keyword。
(2)用大根堆排序的基本思想
① 先將初始檔案r[1..n]建成乙個大根堆。此堆為初始的無序區
② 再將keyword最大的記錄r[1](即堆頂)和無序區的最後乙個記錄r[n]交換,由此得到新的無序區r[1..n-1]和有序區r[n]。且滿足r[1..n-1].keys≤r[n].key
③因為交換後新的根r[1]可能違反堆性質,故應將當前無序區r[1..n-1]調整為堆。
然後再次將r[1..n-1]中keyword最大的記錄r[1]和該區間的最後乙個記錄r[n-1]交換。由此得到新的無序區r[1..n-2]和有序區r[n-1..n]。且仍滿足關係r[1..n-2].keys≤r[n-1..n].keys,相同要將r[1..n-2]調整為堆。
……直到無序區僅僅有乙個元素為止。
(3)大根堆排序演算法的基本操作:
①建堆。建堆是不斷調整堆的過程,從len/2處開始調整,一直到第乙個節點,此處len是堆中元素的個數。建堆的過程是線性的過程。從len/2到0處一直呼叫調整堆的過程。相當於o(h1)+o(h2)…+o(hlen/2) 當中h表示節點的深度。len/2表示節點的個數,這是乙個求和的過程,結果是線性的o(n)。
②調整堆:調整堆在構建堆的過程中會用到。並且在堆排序過程中也會用到。利用的思想是比較節點i和它的孩子節點left(i),right(i),選出三者最大(或者最小)者。假設最大(小)值不是節點i而是它的乙個孩子節點。那邊互動節點i和該節點,然後再呼叫調整堆過程,這是乙個遞迴的過程。調整堆的過程時間複雜度與堆的深度有關係,是lgn的操作,由於是沿著深度方向進行調整的。
③堆排序:堆排序是利用上面的兩個過程來進行的。首先是依據元素構建堆。
然後將堆的根節點取出(通常是與最後乙個節點進行交換)。將前面len-1個節點繼續進行堆調整的過程,然後再將根節點取出,這樣一直到全部節點都取出。堆排序過程的時間複雜度是o(nlgn)。由於建堆的時間複雜度是o(n)(呼叫一次)。調整堆的時間複雜度是lgn,呼叫了n-1次。所以堆排序的時間複雜度是o(nlgn)。
2、堆的儲存
一般用陣列來表示堆,若根結點存在序號0處, i結點的父結點下標就為(i-1)/2。
i結點的左右子結點下標分別為
2*i+1
和2*i+2
。3、堆排序演算法實現(最大堆)
#include void printarray(int thearray, int n)
std::cout << std::endl;
}void adjustheap(int thearray, int n, int start) //從start索引處結點開始調整
} if(leftindex < n) //start索引處結點存在左孩子結點,但不一定存在右孩子結點
} adjustheap(thearray, n, start-1); //再次遞迴調整start索引處的上乙個結點
}void constructheap(int thearray, int n)
void heapsort(int thearray, int n)
int main(int argc, char *ar**) ;
int length = sizeof(myarray) / sizeof(myarray[0]);
constructheap(myarray, length);
heapsort(myarray, length);
printarray(myarray, length);
return 0;
}
4、堆的時間複雜度和空間複雜度
堆的最好、最壞以及平均時間複雜度是o(nlogn).
堆的空間複雜度是o(1).
感想:剛開始實現建立堆時,以為須要建立乙個二叉樹輔助幫助,事實上這個所謂堆(即全然二叉樹)僅僅是邏輯結構。真實的物理結構還是那個順序陣列。在建立大堆或小堆的過程中,均是以順序陣列為基礎,而邏輯上是操作一顆全然二叉樹,故全然不須要建立乙個輔助全然二叉樹。
堆排序實現
今天抽空寫了個堆排序的演算法,廢話不多說,直接上源 include include includeusing namespace std define maxsize 6 void print int a,int size maxsize void percolate up int a,int si...
堆排序實現
1 堆排序演算法描述 1 定義 n個關鍵字序列kl,k2,kn稱為 heap 當且僅當該序列滿足如下性質 簡稱為堆性質 1 ki k 2i 且ki k 2i 1 1 i n 2 當然,這是小根堆,大根堆則換成 號。k i 相當於 二叉樹的非 葉子結點,k 2i 則是左子節點,k 2i 1 是右子節點...
實現堆排序
堆排序是在程式設計中經常用到的東西,在c 的stl底層裡面有make heap,push heap,pop heap 和 sort heap四個介面函式,我們用到的最多的是stl中的priority queue,其中的底層也是利用前面幾個函式實現的。下面我們就自己實現以下堆排序,主要包括調整堆結構,...