堆排序

          在算法导论上看了有关堆排序的介绍,便自己动手写了一下试试手。

          堆排序也是一种比较快速的排序方法。需要几个步骤就行了。所谓堆分为大顶堆和小顶堆。堆也就是一个完全二叉树,大顶堆的叶子结点都比父亲结点小,而小顶堆正好相反,所有的两个儿子结点都比父结点要大。第一步骤就是建堆,建堆的时候可以从后最有一个结点的父结点开始,维护堆的性质,也就是维护堆中任何父亲结点都比儿子结点大这个性质就性了。然后取出堆顶的元素,放到堆尾,缩小堆,继续维护堆的性质,直到只剩下最后一个元素的时候。由于每次取出来的都是最大的元素,放到最后面,这样出来的也就是从小到大排序的。

//维护堆的性质
void heap_max(int *s,int i,int n)
{
    int biggest = i;
    if((LL(i)<=n)&&(s[LL(i)]>s[biggest]))
	biggest = LL(i);
    if((RR(i)<=n)&&(s[RR(i)]>s[biggest]))
	biggest = RR(i);
    if(biggest != i){
	swap(&s[i],&s[biggest]);
	heap_max(s,biggest,n);
     }
}

建堆
void build_heap(int *s,int n)
{
    int i;
    for(i=(n>>1);i>=1;i--)
	heap_max(s,i,n);
    return ;
}


堆排序的过程
void heap_sort(int *s,int n)
{
    int i;
    for(i=n;i>1;i--){
	swap(&s[1],&s[i]);
	heap_max(s,1,i-1);
    }
}


这是前面的一些定义的东西
#define LL(i) ((i)<<1)
#define RR(i) (((i)<<1)+1)

void swap(int *a,int *b)
{
    int t;
    t = *a;
    *a = *b;
    *b = t;
}

        堆有很多用处,比如实现一个优先队列。这样建立队列是用一个已经存在的数组进行建堆的,当然也可以在插入的时候建堆。比如从100万个树中找出最大的一千个数。就可以建立大小为一千的最小堆,一千以后的元素和堆顶的元素进行对比,如果大于就替换并维护,如果小于就算了,这样就可以用大小为一千的内存来找到一百万内的最大的前一千个数字。而且维护起来也比较快。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值