經典排序演算法 堆排序(Heap Sort)

2021-07-24 11:59:40 字數 2013 閱讀 4384

首先堆是乙個完全二叉樹,但同時他具有這樣的要求:每乙個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆;每乙個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆

如下圖是乙個大頂堆

在此要補充乙個二叉樹的性質:二叉樹的某個節點下標為i,則它的左孩子的下標一定為2i,右孩子下標一定為2i+1。

假如現在我們要對這個序列,進行堆排序,我們現在要做的:

1. 首先我們要把這個無序序列變成乙個堆,構成堆之後,由堆的定義我們知道,堆的根節點一定是整個樹當中值最大的。

2. 變成堆後,根節點和樹的最後乙個結點交換位置,然後彈出該節點,剩下的結點再重新構造成乙個新堆。

//具體構建堆的邏輯**

void heapadjust(sqlist *l, int s, int m)

if(temp >= l->r[j])

l->r[s] = l->r[j];

s=j;

}l->r[s] = temp;

}//排序

void heapsort(sqlist *l)

//沒交換一次,就轉換一次為堆

for(i = l->length;i>1;i--)

}

首先根據傳入的下標,獲得乙個結點,開始對這個結點操作;

然後根據這個結點,獲取到它的左右孩子結點(上面提到的二叉樹定義:左孩子為2i, 右孩子為2i+1);

左右孩子比較,得出值大者跟其父節點交換位置。

例如,當i=length/2=4時,獲取到的結點為30,然後再獲取30的左右孩子分別為60,20。由於60大於30,因此30和60交換位置。

最後轉換為堆之後的示意圖:

public

class heapsort

for(int i = size; i > 0; i--)

}public

void heapadjust(int array, int root, int end)

if(temp >= array[i])

array[root] = array[i];

root = i;

}array[root] = temp;

}public

void swap(int array, int i, int j)

public

static

void main(string args);

new heapsort().sort(array);

for(int i = 1; i < array.length; i++)}}

結果:

建堆的時間複雜度:o(n)

排序的時間複雜度:

for迴圈肯定是n的,關鍵是看heapadjust,一開始傳1,n進去,我們看heapadjust裡的時間複雜度是多少

完全二叉樹的性質:

有n個節點的完全二叉樹,深度為 log n(向上取整) + 1

因此傳1,n進去,假設n為9,那麼此時會查詢的節點下標為1,2,4,8,也就是走完了整個樹n個節點的深度(二分查詢)

所以heapadjust的時間複雜度為:o(logn)

所以假如維護k的堆,heapadjust的時間複雜度為:o(logk)

經典演算法 堆排序

堆排序是利用堆的性質來進行排序的乙個演算法。一 堆堆 英語 heap 是電腦科學中一類特殊的資料結構的統稱。堆通常是乙個可以被看做一棵樹的陣列物件。堆總是滿足下列性質 將根節點最大的堆叫做最大堆或大根堆,根節點最小的堆叫做最小堆或小根堆。常見的堆有二叉堆 斐波那契堆等。堆的定義如下 n個元素的序列當...

經典排序演算法 堆排序Heap sort

經典排序演算法 堆排序heap sort 堆排序有點小複雜,分成三塊 第一塊,什麼是堆,什麼是最大堆 第二塊,怎麼將堆調整為最大堆,這部分是重點 第三塊,堆排序介紹 第一塊,什麼是堆,什麼是最大堆 什麼是堆 這裡的堆 二叉堆 指得不是堆疊的那個堆,而是一種資料結構。堆可以視為一棵完全的二叉樹,完全二...

經典排序演算法 堆排序Heap sort

經典排序演算法 堆排序heap sort 堆排序有點小複雜,分成三塊 第一塊,什麼是堆,什麼是最大堆 第二塊,怎麼將堆調整為最大堆,這部分是重點 第三塊,堆排序介紹 第一塊,什麼是堆,什麼是最大堆 什麼是堆 這裡的堆 二叉堆 指得不是堆疊的那個堆,而是一種資料結構。堆可以視為一棵完全的二叉樹,完全二...