STL的is_heap算法

前两天在看Austern的Generic programming and STL,看到关于堆的操作,其中有个函数是is_heap,其复杂度是last - first +1,我没有仔细去看过STL的源代码,就自己想想STL的实现。

 

由于堆从逻辑上讲是一棵完全二叉树,因此自然而然就想到用递归。我就简单的写了下面的用递归判断堆的算法。

bool isheap2(int *arr, int pos, int size){
    int child = pos * 2 + 1;
    if (child < size){
        if (arr[pos] < arr[child])return false;
        if (isheap2(arr,child,size)){
            child ++;
            if (child < size){
                if (arr[pos] < arr[child])return false;
                return isheap2(arr,child,size);
            }
        }else{
            return false;
        }
    }    
    return true;
}

但是仔细分析了一下,觉得STL的实现应该效率更高,我想不会用递归。就去VC 6看看,结果发现VC6中的STL居然没有is_heap,这简直是...,又去Linux下看看SGI的STL实现,发现确实STL的实现更高效。我就按照STL的实现写了个简单版本。

 

bool isheap(int *arr, int size){
    int parent = 0;
    for (int child = 1;child<size;++child){
        if (arr[parent]<arr[child])
            return false;
        if ((child & 1) ==0)
            ++parent;
    }
    return true;
}
它利用堆的逻辑结构特点,通过(child & 1) ==0来判断当前节点是否为右儿子,如果是则说明当前parent的两个儿子都已经进行过比较,parent自增1指向下一个节点。

而且这里循环体中的自增都采用的是前缀自增,用前缀自增比后缀自增少进行一次内存的分配和对象的构造、析构和拷贝构造,效率更高。尤其是当数据量很大的时候,这会产生显著的效果。

 

从这个STL的算法其实我们可以扩展到n叉树,采用一种比较灵活的办法来获取其n个儿子。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值