堆排序(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 即任何一非葉節點的關鍵字不大於或者不小於其左右孩子節點的...