演算法系列之一 堆排序

2021-09-02 02:27:27 字數 3395 閱讀 7715

前序:

(二叉)堆資料結構是一種陣列物件,它可以被視為一棵完全二叉樹。樹中每個節點與陣列中存放該節點值的那個元素對應。

樹的每一層都是填滿的,最後一層除外。

樹的根為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 每個結點的左子樹和右子樹都是乙個二叉堆...