前序:
(二叉)堆資料結構是一種陣列物件,它可以被視為一棵完全二叉樹。樹中每個節點與陣列中存放該節點值的那個元素對應。
樹的每一層都是填滿的,最後一層除外。
樹的根為a[1] (在這裡是從1開始的,也可以從0開始),給定了某個節點的下標i,其父節點為i/2,左二子為2*i,右兒子為2*i+1。
二叉堆滿足二個特性:
1.父結點的鍵值總是大於或等於(小於或等於)任何乙個子節點的鍵值。
2.每個結點的左子樹和右子樹都是乙個二叉堆(最大堆或最小堆)。
當父結點的鍵值總是大於或等於任何乙個子節點的鍵值時為最大堆。
當父結點的鍵值總是小於或等於任何乙個子節點的鍵值時為最小堆。
保持堆的性質:
maxheap是對最大堆進行操作的最重要的子程式。
以i為根的子樹:
在演算法每一步中,從a[i], a[left(i)], a[right(i)]找出最大值,並將其下標存在largestindex中。如果a[i]是最大的,則以i為根的子樹已是最大堆,程式結束。
否則i的某個子結點中有最大元素則交換a[i],a[largetindex],從而使i及子女滿足堆性質。下標為largestindex的結點在交換後的值為a[i],以該結點為根的子樹又有可能違反最大堆的性質,因而又要對該子樹遞迴呼叫maxheap,重新使子樹平衡。
[cpp]view plain
copy
//調整以index為根的子樹
//n:堆中元素個數
intmaxheap(
inta,
intindex,
intn)
if(rightindex<=n&&a[rightindex]>a[largestindex])
//如果a[index]是最大的,則以index為根的子樹已是最大堆否則index的子節點有最大元素
//則交換a[index],a[largetindex],從而使index及子女滿足堆性質
inttemp; if
(largestindex!=index)
return0;
} 建堆:
我們可以自底向上的用maxheap來將乙個陣列a[1-n]變成乙個最大堆,子陣列a[n/2+1,........n]中的元素是樹中的葉子,因此每個都可以看做只含乙個元素的堆,滿足最大堆的要求,不用調整。所以只需調整以a[n/2........1]中元素為根的子樹使之成為最大堆。
[cpp]view plain
copy
//建堆:將乙個陣列a[1-n]變成乙個最大堆
intbuildmaxheap(
inta,
intn)
return0;
} a陣列1673
2017
8初始堆:
自底向上從最後乙個非葉節點開始調整:
每次調整都是從父節點、左孩子節點、右孩子節點三者中選擇最大者跟父節點進行交換(交換之後可能造成被交換的孩子節點不滿足堆的性質,因此每次交換之後要重新對被交換的孩子節點進行調整)。
堆排序:
開始時,堆排序先用buildmaxheap將輸入陣列a[1-n]構造成乙個最大堆。又因為陣列中最大元素在根a[1],則可以通過它與a[n]交換來達到最終的正確位置。現在,如果從堆中」去掉「結點n(不是真的刪除,而是通過修改堆的元素個數n),可以很容易的將a[1-(n-1)]建成最大堆。原來根的子女依舊是最大堆,二新交換的根元素很有可能違背最大堆的性質。這時呼叫maxheap重新調整一下。在a[1-(n-1)]中構造出最大堆。堆排序不斷重複這一過程,堆的大小由n-1一直降到2.從而完成排序的功能
[cpp]view plain
copy
//堆排序
紅色為排序後的結果;
**:
[cpp]view plain
copy
#include
#include
//調整堆
intmaxheap(
inta,
intindex,
intn)
if(rightindex<=n&&a[rightindex]>a[largestindex])
//如果a[index]是最大的,則以index為根的子樹已是最大堆否則index的子節點有最大元素
//則交換a[index],a[largetindex],從而使index及子女滿足堆性質
inttemp; if
(largestindex!=index)
return0;
}//建堆:將乙個陣列a[1-n]變成乙個最大堆
intbuildmaxheap(
inta,
intn)
return0;
}//堆排序
intheapsort(
inta,
intn)
return0;
}int
main();
heapsort(a,n);
for(
inti=1;i<=n;i++)
return0;
}
排序演算法一 堆排序
一 演算法介紹 堆排序 heapsort 是指利用堆積樹 堆 這種 資料結構 所設計的一種 排序演算法 它是選擇排序的一種。可以利用 陣列的特點快速定位指定索引的元素。堆分為大根堆和小根堆,是 完全二叉樹 大根堆的要求是每個節點的值都不大於其父節點的值,即 a parent i a i 在陣列的非降...
演算法系列7 堆排序
堆排序 是指利用堆這種資料結構所涉及的一種排序演算法。堆積是乙個近似完全二叉樹的結構,並同時滿足堆積的性質 即子節點的鍵值或索引總是大於或者小於它的父節點 時間複雜度平均為o nlog2n 最好為o nlog2n 最壞o nlog2n 空間複雜度為o 1 不穩定排序 d0 99 5,36 7,22 ...
經典排序演算法系列7 堆與堆排序
堆排序與快速排序,歸併排序一樣都是時間複雜度為o n logn 的幾種常見排序方法。學習堆排序前,先講解下什麼是資料結構中的二叉堆。二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足二個特性 1 父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值。2 每個結點的左子樹和右子樹都是乙個二叉堆...