堆排序在最坏的情况下,其时间复杂度也能达到O(nlogn)。相对于快速排序来说,这是它最大的优点,此外,堆排序仅需要一个记录大小供交换用的辅助存储空间。
堆排序的数据结构是二叉堆,二叉堆的特点有两个,一个是它是一棵完全二叉树,另一个是它的根结点小于孩子结点,所以我们很容易找到它的最小结点----根结点;当然如果你想找到最大结点的话,那就要扫描所有的叶子结点,这是很费时间的,如果你想找的是最大结点的话,你最好把它弄成一个大顶堆,即一棵根结点大于孩子结点的完全二叉树。
二叉堆通常用数组来实现,它舍弃下标0,从下标1开始置数,则很容易满足,对于数组中任意位置i上的元素,其左儿子的位置在2i上,右儿子的位置在2i+1上,双亲的位置则在i/2上。
堆排序的算法之一是把数组构建成二叉堆----这只要增添一个长度为n+1的辅助空间,然后把原数组的元素依次插入到二叉堆即可。然后删除二叉堆的根,把它作为排序后的数组的第一个元素,然后使二叉堆的长度减1,并通过上移使得新得到的序列仍为二叉堆,再提取新二叉堆的第一个元素到新数组。依此类推,直到提取最后一个元素,新得到的数组就是排序后的数组。
堆排序在最坏的情况下,其时间复杂度也能达到O(nlogn)。相对于快速排序来说,这是它最大的优点,此外,堆排序仅需要一个记录大小供交换用的辅助存储空间。
堆排序的数据结构是二叉堆,二叉堆的特点有两个,一个是它是一棵完全二叉树,另一个是它的根结点小于孩子结点,所以我们很容易找到它的最小结点----根结点;当然如果你想找到最大结点的话,那就要扫描所有的叶子结点,这是很费时间的,如果你想找的是最大结点的话,你最好把它弄成一个大顶堆,即一棵根结点大于孩子结点的完全二叉树。
二叉堆通常用数组来实现,它舍弃下标0,从下标1开始置数,则很容易满足,对于数组中任意位置i上的元素,其左儿子的位置在2i上,右儿子的位置在2i+1上,双亲的位置则在i/2上。
堆排序的算法之一是把数组构建成二叉堆----这只要增添一个长度为n+1的辅助空间,然后把原数组的元素依次插入到二叉堆即可。然后删除二叉堆的根,把它作为排序后的数组的第一个元素,然后使二叉堆的长度减1,并通过上移使得新得到的序列仍为二叉堆,再提取新二叉堆的第一个元素到新数组。依此类推,直到提取最后一个元素,新得到的数组就是排序后的数组。

1.INSERT
思路是基于一种“上滤”的策略,设堆为H,待插入的元素为X,首先在size+1的位置建立一个空穴,然后比较X和空穴的爸爸的大小,把“大的爸爸”换下来,以此推进,最后把X放到合适的位置。

2.DELETEMIN
与上面的上滤对应,这将是一种“下滤”的策略,就是逐层推进,把较小的孩子换上来,这里面有个小的问题在具体算法实现上要注意,设堆的最后一个元素是L,在推进到倒数第二层时,将导致最后一层的某个孩子被换上去而产生一个洞,这时候为了保持堆的结构,必须把最后一个元素运过去补上,此时就存在一个问题,如果L比那个孩子小的话就不能保证堆序的性质了,所以在程序中要加一个if语句来进行这个边界条件的处理,还是那句话,对于一个完整的程序,算法是重要的一方面,而对算法边界问题的处理则是更重要的一方面。
#include <stdio.h>
#include <stdlib.h>

void push_heap(int *array, int pos, int value)
{
int i;
for(i=pos; i/2>0 && array[i/2]>value; i/=2) {
array[i] = array[i/2];
}
array[i] = value;
}

void make_heap(int *data, int *array, int len)
{
int i = 0;
for(; i<len; ++i)
{
push_heap(array, i+1, data[i]);
}
}

int pop_heap(int *array, int last)
{
int value = array[1];
array[1] = array[last];
int i=1;
while(2*i < last) {
int min = array[2*i] < array[2*i+1] ? array[2*i] : array[2*i+1];
int pos = array[2*i] < array[2*i+1] ? (2*i) : (2*i+1);
if(array[i] > min) {
int tmp = array[i];
array[i] = min;
array[pos] = tmp;
i = pos;
}
}
return value;
}

void sort_heap(int *data, int *array, int len)
{
int i = 0;
for(; i<len; ++i) {
data[i] = pop_heap(array, len-i);
}
}

int main()
{
int data[] = {12, 34, 23, 3, 1, 45, 87, 99};
int array[10];
int i = 1;
make_heap(data, array, 8);
for(; i<=8; ++i) {
printf("%d ", array[i]);
}
printf("\n");
sort_heap(data, array, 8);
for(i=0; i<8; ++i) {
printf("%d ", data[i]);
}
printf("\n");
system("PAUSE");
return 0;
}

转自http://blog.chinaunix.net/u2/76292/showart_1993970.html

 posted on 2010-06-17 16:59  chao_yu  阅读(1856)  评论(0编辑  收藏  举报