堆排序是一種樹形選擇排序方法,它的特點是:在排序過程中,將l[1…n]看成是一棵完全二叉樹的順序儲存結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關係,在當前無序區中選擇關鍵字最大(或者最小)的元素。
堆的定義如下:n個關鍵字序列l[1…n]稱為堆,當且僅當該序列滿足:
①l(i)≤l(2i)且l(i)≤l(2i)或 ②l(i)≥l(2i)且l(i)≥l(2i+1)
滿足第一種情況的堆稱為小根堆,滿足第二種情況的稱為大根堆。顯然,在大根堆中,最大元素存放在根結點中,且對其中任意乙個非根結點,它的值小於或等於其雙親結點值。小根堆的定義剛好相反,根結點是最小元素。
堆排序的關鍵是構造初始堆,對初始序列建堆,就是乙個反覆篩選的過程。n個結點的完全二叉樹,最後乙個結點是第[n/2]個結點的孩子。對第[n/2]哥結點為根的子樹篩選(對於大根堆:若根結點的關鍵字小玉左右子女中關鍵字較大者,則交換),使該子樹成為堆。之後向前依次對各結點([n/2]-1~1)為根的子樹進行篩選,看該結點值是否大於其左右子結點的值,若不是,將左右子結點中較大值與其交換,交換後可能會破壞下一級的堆,於是繼續採用上述方法構造下一級的堆,直到以該結點為根的子樹構成堆位置。反覆利用上述調整堆的方法建堆,直到根結點。
}a[k]=a[0];//被篩選結點的值放入最終位置
}
void heapsort(elemtype a,int len)
}
同時,堆也支援刪除和插入操作。由於堆頂元素或為最大值或最小值,刪除堆頂元素時,先將堆的最後乙個元素與堆頂元素交換。由於此時堆的性質被破壞,將堆頂元素向下調整操作。對堆進行插入操作時,先將新結點放在堆的末端,再對這個新結點執行向上調整操作。
下面是向上調整堆的演算法:
void adjustup(elemtype a,int k)
a[k]=a[0];//複製到最終位置
}
空間複雜度:僅使用了常數個輔助單元,所以空間複雜度為o(1)。
時間複雜度:建堆時間為o(n),之後有n-1次向下調整的操作,每次調整的時間複雜度為o(log₂n)。所以時間複雜度為o(nlog₂n)。
穩定性:在進行篩選時,有可能把後面相同關鍵字的元素調整到前面,所以堆排序演算法是一種不穩定的排序方法。例如,表l=,構造初始堆時,可能將2交換到堆頂,此時l={2,1,2},最終排序序列為l={1,2,2},顯然,2和2的相對次序已經發生了變化。
資料結構 堆排序 堆排序 Heap Sort
堆排序是一種選擇排序,其時間複雜度為o nlogn 堆的定義 n個元素的序列當且僅當滿足下列關係之一時,稱之為堆。情形1 ki k2i 且ki k2i 1 最小化堆或小頂堆 情形2 ki k2i 且ki k2i 1 最大化堆或大頂堆 其中i 1,2,n 2向下取整 若將和此序列對應的一維陣列 即以一...
資料結構 堆排序
include include void maxheapify int a,int length,int i void buildmaxheapify int a,int length void heapsort int a,int length void main void printf heap...
資料結構 堆排序
1 堆排序的時間複雜度與歸併排序相同,o nlogn 堆排序的優勢在與他只需要固定數量的額外空間,堆排序要比空間複雜性為o n 的歸併排序稍微慢一些,但是比空間複雜性為o 1 的歸併排序要快。2 對序列 26,5,77,1,61,11,59,15,48,19 進行堆排序 過程 調整最大堆 二叉堆 v...