建堆的两种方法&小疑惑

堆,有时也被叫做优先队列。
更多的应用在需要优化一些效率的地方。各类语言中也提供了一些自治的优先队列的函数。C++就有priority_queue这个玩意。
但是这并不代表着就需要写建堆的函数了。
可是我有时写建堆函数的时候遇到了一些很疑惑的点,现在先记录下来。供以后研究吧。
第一种方法好像叫做筛选法建堆。也是教的那种。
具体思想就是从最后一棵子树调整起,保持到每颗子树都是堆,然后这么调整下去,直至到堆顶。也就建完堆了。
这种调整方法需要注意的点在于,每次一颗新子树调整的过程可能会影响到之前就已经调整好的子树,所以是一直找到结尾,而不是就在当前这里写完。
具体代码

void AdjustHeap(int heap[],int n){
    for(int i = n/2;i >= 1;i--)
    {
		int par = i;
		int tmp = heap[par];
		for(int lch = par*2; lch <= n;i++)
		{
			if(lch + 1 <= n && heap[lch+1] < heap[lch])
				lch++;
			if(heap[lch] > tmp)
				break;
			heap[par] = heap[lch];
			par = lch;
		}
		heap[par] = tmp;
    }
 }

还有一种方法则是像插入排序那样,每一步都是有序的,然后保证到最后都是有序的。
代码如下

void AdjustHeap(int heap[],int n){
    for(int i=1; i <= n; i++)
    {
        int k=i;
        while(k>1 && heap1[k] < heap1[k/2])
        {
            swap(heap1[k],heap1[k/2]);
            k=k/2;
        }
    }
  }

以上两种代码都是默认从1到n的数组下标。
但是这样会出现一个问题,就是上面两种代码对于同一组数据会有不同的结果。
比如下面这个
8
7 5 8 4 2 3 6 1
对于大顶堆 上述两种方法得到的结果是一样的
都是
8 5 7 4 2 3 6 1
而对于小顶堆
插入法是
1 2 3 4 5 8 6 7
筛选法是
1 2 3 4 7 8 6 5
之前写题目时遇到过插入法对的题目,有的又是筛选法对的题目,只能是把这两种方法都记住。方便使用了。
没想到之前抄的网上写的筛选法的代码有那么多的漏洞,汗

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值