堆排序實現及應用

2021-06-26 01:44:14 字數 1802 閱讀 5945

堆排序(heapsort)是指利用堆這種資料結構所設計的一種排序演算法。堆積是乙個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。

一般都用陣列來表示堆,i結點的父結點下標就為(i – 1) / 2。它的左右子結點下標分別為2 * i + 1和2 * i + 2。如第0個結點左右子結點下標分別為1和2。這是從0開始的結構。

堆分為最大堆(大頂堆)和最小堆(小頂堆),顧名思義就是父節點和左右孩子節點的關係,如果父節點大於所有的子節點的堆就是大頂堆,父節點小於所有子節點的堆就是小頂堆,選擇大頂堆和小頂堆決定了排序的順序,是從大到小還是從小到大排序。

1、建立及堆的插入

在堆中插入元素,其實是乙個上浮的操作,因為插入節點是在堆的最後,這個節點可能會破壞堆,所以需要通過調節這個插入元素的位置來最終恢復堆的有序性,這個操作就是乙個上浮的操作。

上浮**如下:

//k是插入元素的位置

void swim(int a, int k)

else}}

2、刪除

按照定義刪除只能是刪除第乙個節點,也就是根節點,為了方便重建堆,所以需要將最後乙個節點替換到根節點,然後重新整理堆,這時就需要下降(sink)操作,將根節點逐漸的向下交換,最後使堆達到定義的要求。

**如下:

//n是節點總數,刪除總是從根節點開始

void sink(int a, int n, int i)

else}}

3、建堆

如何將乙個普通的陣列建成乙個堆呢,那就需要對當前堆中的非葉子節點進行sink操作,最後達到堆的要求

**如下:

void build_heap(int a, int n)

}

回到正題,堆排序其實就是不斷的交換根節點和最後節點的過程,不斷的縮小未排序集合的過程,這其中使用的就是sink操作

void heap_sort(int a, int n)

}

最後將整體做了乙個測試,**如下:

#include void swap(int *a, int *b)

//k是插入元素的位置

void swim(int a, int k)

else

}}//n是節點總數,刪除總是從根節點開始

void sink(int a, int n, int i)

else

}}void build_heap(int a, int n)

}void heap_sort(int a, int n)

}int main()

; swim(a, 3);

int i;

for(i = 0; i < 4; i++)

printf("\n");

int b[4] = ;

sink(b, 4, 0);

for(i = 0; i < 4; i++)

printf("\n");

int c[10] = ;

build_heap(c, 10);

for(i = 0; i < 10; i++)

printf("\n");

heap_sort(c, 10);

for(i = 0; i < 10; i++)

printf("\n");

}

堆排序實現及應用

堆排序 heapsort 是指利用堆這樣的資料結構所設計的一種排序演算法。堆積是乙個近似全然二叉樹的結構。並同一時候滿足堆積的性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點。一般都用陣列來表示堆,i結點的父結點下標就為 i 1 2。它的左右子結點下標分別為2 i 1和2 i 2。如第0個結...

堆排序及C 實現

1.使用其中一種堆結構,二叉堆也可以實現排序。背景 1 完全二叉樹 若設二叉樹的高度為h,除第 h 層外,其它各層 1 h 1 的結點數都達到最大個數,第h層有 葉子結點,並且葉子結點都是從左到右依次排布,這就是 完全二叉樹。二叉堆使用完全二叉樹的結構實現 2 滿二叉樹 除了葉結點外每乙個結點都有左...

堆排序原理及實現

堆排序 堆排序是利用堆的性質進行的一種選擇排序。下面先討論一下堆。1.堆堆實際上是一棵完全二叉樹,其任何一非葉節點滿足性質 key i key 2i 1 key i key 2i 2 或者key i key 2i 1 key key 2i 2 即任何一非葉節點的關鍵字不大於或者不小於其左右孩子節點的...