堆排實際上是一種選擇排序,堆其實就是一棵完全二叉樹,任何一非葉節點的關鍵字不大於或者不小於其左右孩子節點的關鍵字。
堆分為大頂堆和小頂堆,滿足key[i]>=key[2i+1]&&key>=key[2i+2]稱為大頂堆,滿足 key[i]<=key[2i+1]&&key[i]<=key[2i+2]稱為小頂堆。由上述性質可知大頂堆的堆頂的關鍵字肯定是所有關鍵字中最大的,小頂堆的堆頂的關鍵字是所有關鍵字中最小的。
利用大頂堆(小頂堆)堆頂記錄的是最大關鍵字(最小關鍵字)這一特性,使得每次從無序中選擇最大記錄(最小記錄)變得簡單。
基本思想(小頂堆):
1)將初始待排序關鍵字序列(r1,r2….rn)構建堆,此堆為初始的無序區;
2)將堆頂元素r[1]與最後乙個元素r[n]交換,此時得到新的無序區(r1,r2,……rn-1)和新的有序區(rn),且滿足r[1,2…n-1]<=r[n];
3)由於交換後新的堆頂r[1]可能違反堆的性質,因此需要對當前無序區(r1,r2,……rn-1)調整為新堆,然後再次將r[1]與無序區最後乙個元素交換,得到新的無序區(r1,r2….rn-2)和新的有序區(rn-1,rn)。不斷重複此過程直到有序區的元素個數為n-1,則整個排序過程完成。
操作過程如下:
1)初始化堆:將r[1..n]構造為堆;
2)將當前無序區的堆頂元素r[1]同該區間的最後乙個記錄交換,然後將新的無序區調整為新的堆。
因此對於堆排序,最重要的兩個操作就是構造初始堆和調整堆,其實構造初始堆事實上也是調整堆的過程,只不過構造初始堆是對所有的非葉節點都進行調整。
實現**(小頂堆):
#include
void heapadjust(int a, int start, int end )//調整堆
if(right <= end && min > a[right])
if(index == start)
break;
a[start] = min;//找出左右節點和父節點中最小的那乙個,把最小的賦給父節點
start = index;
}a[start] = temp;
}void heapsort(int a,int n )//進行堆排
}int main()
Python 實現快排 堆排
原理 公升序 選取陣列的首個元素做為中間值,快取這個中間值,該位置變為空 從右到左和中間值對比,找到第乙個小於中間值的元素,把該值放到左邊的空位,該位置變為空 從左到右和中間值對比,找到第乙個大於中間值的元素,把該值放到右邊的空位,該位置變為空 重複步驟2和3,直到左右空位相交,然後把快取的中間值填...
快排與堆排的比較 std sort實現分析
今天面試被問到了快排與堆排的應用場景,思考了一下只答上來了資料基本有序的情況下堆排優於快排以及topk問題選擇堆排,更進一步卻答不上來。後來發現其實堆排序和快速排序平均複雜度雖然都是o nlogn 但是在最差情況下堆排複雜度也是o nlogn 這一點比快排要好。但是稍微實驗一下就能發現,堆排序雖然平...
堆排的學習
堆排沒有用到遞迴,一般堆排是兩個步驟,1 建立堆 2 不斷的調整堆,進行排序 首先,我們學習堆排就必須了解什麼是堆,堆其實是一種比較特殊的資料結構,分為大根堆和小根堆,堆有兩個性質 1 它是乙個完全二叉樹,每個節點都比它的子樹所有節點大 大根堆 2 由於他是乙個完全二叉樹,那麼它的每個位置都與陣列的...