【数据结构】筛选法建堆

如果已经存在N个数据元素,如何将这些元素按照堆的要求存储在一个一维数组中呢?这就是堆的建立问题。
首先我们可以想到按照之前的堆的插入算法将这N个元素依次插入一个空堆中,分析时间复杂度,每插入一个元素最多要进行logN(即堆的深度)次比较,所以对于N个元素用插入法建堆的时间复杂度是O(NlogN)。
这里要介绍的是筛选法建堆,它可以在线性时间复杂度下完成建堆。以最大堆为例介绍具体操作过程:

  1. 首先将N个数据元素存入一个一维数组,并把这个数组视作一棵完全二叉树。
  2. 从二叉树的最后一个非叶结点开始用从上向下过滤的方法调整以该非叶结点为根节点的二叉树为最大堆。
  3. 对前面的结点依次执行2的操作直到根结点执行完成为止。此时这棵二叉树就调整为了一个最大堆。

    注:从上向下过滤是指从二叉树的根结点开始,比较根结点和它的子结点,如果根结点比子结点中最大的那个小的话,就交换父节点和子结点的值,之后对以之前子结点为根节点的二叉树重复执行上述操作。

图解(图片非原创,侵删)

下面是代码实现

typedef struct heap{
    int *Elements;//存放堆元素的数组
    //Elements[0]中存放一个大于堆中所有可能元素的哨兵,
    //所以堆顶位置在Elements[1]处

    int Size;//堆的当前元素个数
    int Capacity;//堆的最大容量
}* MaxHeap;

void BuildMaxHeap(MaxHeap H)
{
    int parent,child,temp;
    for(int i = H->Size/2; i>0; i--){
        parent = i;
        temp = H->Elements[i];
        while(parent*2<=H->Size){
            child = parent*2;
            if((child!=H->Size)&&(H->Elements[child]<H->Elements[child+1]))
                child++;
            if(temp<H->Elements[child]){
                H->Elements[parent] = H->Elements[child];
                parent = child;
            }
            else
                break;
        }
        H->Elements[parent] = temp;
    }
    printf("%d\n",H->Size);
}
  • 38
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值