堆排序詳解

2021-06-29 02:39:12 字數 1545 閱讀 2571

一、堆的定義

堆的定義如下:n個關鍵字序列l[n]成為堆,當且僅當該序列滿足:

①l(i) <= l(2i)且l(i) <= l(2i+1)  或者  ②l(i) >= l(2i)且l(i) >= l(2i+1)   其中i屬於[1, n/2]。

滿足第①種情況的堆稱為小根堆(小頂堆),滿足第②種情況的堆稱為大根堆(大頂堆)。在大根堆中,最大元素存放在根結點中,且對任一非根結點,它的值小於或等於其雙親結點值。小根堆則恰恰相反,小根堆的根結點存放的是最小元素。

二、構造初始堆

堆排序的關鍵就是構造初始堆。n個結點的完全二叉樹中,最後乙個結點是第n/2(向下取整)個結點的孩子。所以構造初始堆的流程是:對第n/2(向下取整)個結點為根的子樹進行篩選(以大根堆為例,若根結點的關鍵字小於左右子女中關鍵字的較大者,則交換),使該子樹成為堆。之後向前依次對從n/2-1到1的各結點為根的子樹進行篩選,看該結點值是否大於其左右子結點的值,若不是,將左右子結點中較大值與之交換,交換後可能會破壞下一級的堆,於是繼續採用上述方法構造下一級的堆,直到以該結點為根的子樹構成堆為止。反覆利用上述調整堆的方法建堆,直到根結點。

由於在陣列中下標從0開始,所以在堆中i的左子結點為2*i+1,右子結點為2*i+2。

三、堆排序

建成初始堆,由於堆本身的特點(以大根堆為例),堆頂元素就是最大值。輸出堆頂元素後,通常將堆底元素送入堆頂,此時根結點已不滿足大根堆的性質,堆被破壞。這時將堆頂元素向下調整使其繼續保持大根堆的性質,再輸出堆頂元素。如此重複,直到堆中僅剩下乙個元素為止。

四、效能分析

時間複雜度:向下調整的時間與樹高有關,為o(h)。可以證明在元素個數為n的序列上建堆,其時間複雜度為o(n)。之後還有n-1次向下調整操作,每次調整的時間為o(h),故在最好,最壞和平均情況下,堆排序的時間複雜度為o(nlogn)。

空間複雜度:僅使用了常數個輔助單元,空間複雜度為o(1)。

穩定性:不穩定。

#include using namespace std;

//調整堆元素 大頂堆

void adjustdown( int arr, int i, int len )

if( temp < arr[largest] )else

}arr[i] = temp;

for(int i =0; iarr[largest] )

else

} arr[i] = temp;

}//建堆

void buildmaxheap( int arr, int len )

}int main()

; int nlen = sizeof(arr)/sizeof(int);

heapsort(arr, nlen);

for(int i=0; icout

return 0;

}

排序詳解 堆排序

堆排序 heapsort 是指利用堆積樹 堆 這種資料結構所設計的一種排序演算法,它是選擇排序的一種。可以利用陣列的特點快速定位指定索引的元素。堆分為大根堆和小根堆,是完全二叉樹。大根堆的要求是每個節點的值都不大於其父節點的值,即a parent i a i 在陣列的非降序排序中,需要使用的就是大根...

堆排序詳解

public class heapsort 此時已經完成了最大堆的構建,下面進行排序。for int i len 1 i 0 i 維護最大堆,保證父節點大於等於子節點 public static void maxheapify int a,int index,int len if rightchil...

堆排序詳解

基本概念 要了解堆排序,首先要了解什麼是堆,要了解堆,還要先了解什麼是完全二叉樹。一 什麼是完全二叉樹?完全二叉樹 complete binary tree 有嚴格的形狀要求 從根節點起每一層從左到右填充。一棵高度為d的完全二叉樹除了d 1層以外,每一層都是滿的。底層葉節點集中在左邊的若干位置上。完...