經典演算法學習 堆排序

2021-07-09 19:59:42 字數 1607 閱讀 3644

堆排序是相對其他排序稍微麻煩的排序,是一種利用堆的性質進行的選擇排序。堆其實是一棵完全二叉樹,只要任何乙個非葉節點的關鍵字不大於或者不小於其左右孩子節點,就可以形成堆。堆分為大頂堆和小頂堆。由上述性質可知大頂堆的堆頂的關鍵字是所有關鍵字中最大的,小頂堆的堆頂的關鍵字是所有關鍵字中最小的。堆排序同快速排序一樣都是不穩定排序。示例**上傳至:

堆排序的思想:利用大頂堆(小頂堆) 堆頂記錄的是最大關鍵字(最小關鍵字)這一特性,使得每次從無序中選擇最大記錄(最小記錄)變得簡單。注意:大頂堆構造的是遞增序列,小頂堆構造的是遞減序列。

(1)將初始待排序關鍵字序列(r0,r1....rn-1),構建成大頂堆,此堆為初始的無序區;

(2)將堆頂元素r[0]與最後乙個元素r[n-1]交換,此時得到新的無序區(r0,r1....rn-2)和新的有序區(rn-1),且滿足r[0,1...n-2]<=r[n-1];

(3)由於交換後新的堆頂r[0]可能違反堆的性質,因此需要對當前無序區(r0,r1...rn-2)調整為新堆,然後再次將r[0]與無序區最後乙個元素交換,得到新的無序區(r0,r1...rn-3)和新的有序區(rn-2,rn-1).不斷重複此過程知道有序區的元素個數為n-1,則整個排序過程完成。

操作過程如下:

(1)初始化堆:將[0...n-1]構造為堆;

(2)將當前無序區的堆頂元素r[0]同該區間的最後乙個記錄交換,然後將新的無序區調整為新的堆;

因此對於堆排序,最重要的兩個操作就是構造初始堆和調整堆,其實構造初始堆也是調整堆的過程,只不過構造初始堆是對所有的非葉節點都進行調整。

例項**如下:

//

// main.c

// train

//// created by chenyufeng on 16/1/30.

//#include void buildheap(int *a,int size);

void swap(int *a,int *b);

void heapsort(int *a,int size);

void heapadjust(int *a,int i,int size);

int main(int argc,const char *argv);

heapsort(a, 5);

for (int i = 0; i < 5; i++)

return 0;

}//建立堆

void buildheap(int *a,int size)

}//交換兩個數

void swap(int *a,int *b)

//堆排序

void heapsort(int *a,int size)

}//調整堆

void heapadjust(int *a,int i,int size)

if (rchild <= size && a[rchild] > a[max])

if (i != max) }}

說明一下,堆排序的時間複雜度為o(n*logn),空間複雜度為o(1).是一種不穩定排序。

本文參考:

演算法學習 堆排序

一 關於二叉樹和堆的基本概念 1 二叉樹 每個節點,最多有2個子樹的數結構。左右子樹,也是最多有2個子節點。2 滿二叉樹 除最後一層外,每個節點都有2個子節點。3 完全二叉樹 存在的節點,和滿二叉樹的節點完全對應。4 堆 max heap 最大的元素永遠在根節點 任一非終端節點資料均不小於其左 右孩...

排序演算法學習之堆排序

堆排序 英語 heapsort 是指利用 堆這種資料結構所設計的一種 排序演算法 堆是乙個近似 完全二叉樹 的結構,並同時滿足堆積的性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點。簡單的就是將乙個陣列看作是乙個二叉樹,然後每個父節點跟自己的子節點比較 最大的就成為父節點。如下圖 當第一輪對...

演算法學習之 堆排序

1.堆是實現優先佇列的首選資料結構,最常見的是二叉堆。2.堆的性質 小頂堆 每乙個父節點的值總是不大於它的孩子節點的值。大頂堆 每乙個父節點的值總是不小於它的孩子節點的值。堆包含的操作有 insert 插入操作 extractmin 提取最小 用於小頂堆 exectractmax 提取最大 用於大頂...