堆的C++实现

  • 性质: 1.堆是一颗完全二叉树,用数组实现。
       2.堆中存储数据的数据是局部有序的。
  • 最大堆:1.任意一个结点存储的值都大于或等于其任意一个子结点中存储的值。
         2.根结点存储着该树所有结点中的最大值。
  • 最小堆:1.任意一个结点存储的值都小于或等于其惹你一个子结点存储的值。
         2.根结点存储着该树所有结点中的最小值。
  • 无论最小堆还是最大堆,任何一个结点与其兄弟结点之间都没有必然联系。
  • 以下给出最大堆的类声明及其成员函数的实现:
template<typename E> class heap{
private:
    E* Heap;    //堆序列的指针
    int maxsize;   //堆的最大容量
    int n;      //堆里面的元素数量

    //将元素放在它应在的位置
    void siftdown(int pos)
    {
        while (!isLeaf(pos))
        {
            int j = leftchild(pos); 
            int rc = rightchild(pos);
            if ((rc < n)&& prior(Heap[rc], Heap[j]))
                j = rc;
            if (prior(Heap[pos], Heap[j]))    return;
            swap(Heap, pos, j);
            pos = j;
        }
    }
public:

    //构造函数
    heap(E* h, int num, int max)
    {
        Heap = h; n = num; maxsize = max;
        buildHeap();
    }
    //返回堆的大小
    int size() const
    {return n;}
    //判断是否为叶节点
    bool isLeaf(int pos) const
    {
        return (pos >= n / 2) && (pos < n);
    }
    //返回左节点
    int leftchild(int pos) const
    {
        return 2 * pos + 1;
    }
    //返回右节点
    int rightchild(int pos) const
    {
        return 2 * pos + 2;
    }
    //返回父节点
    int parent(int pos) const
    {
        return (pos - 1) / 2;
    }
    //建堆
    void buildHeap()
    {
        for (int i = n / 2 - 1; i >= 0; i--) siftdown(i);
    }
    //插入一个元素
    void insert(const E& it)
    {
        assert(n < maxsize, "Heap is full");
        int curr = n++;
        Heap[curr] = it;
        while ((curr != 0) && (prior(Heap[curr], Heap[parent(curr)])))
        {
            swap(Heap, curr, parent(curr));
            curr = parent(curr);
        }
    }
    //移除根节点
    E removefirst()
    {
        assert(n > 0, "Heap is empty");
        swap(Heap, 0, --n);
        if (n != 0)siftdown(0);
        return Heap[n];
    }
    //移除任意一个元素
    E remove(int pos)
    {
        assert((pos >= 0)&&(pos < n), "Bad position");
        if (pos == (n - 1)) n--;
        else
        {
            swap(Heap, pos, --n);
            while ((pos) != 0 && (prior(Heap[pos], Heap[parent(pos)])))
            {
                swap(Heap, pos, parent(pos));
                pos = parent(pos);
            }
            if (n != 0) siftdown(pos);
        }
        return Heap[n];
    }
    //判断第一个参数是否再第二个参数之前
    bool prior(E a, E b)
    {

        if (a > b)   return true;
        else return false;
    }
    //交换值
    void swap(E* heap, int i, int j)
    {
        E temp;
        temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }
    //打印
    void print()
    {
        for (int i = 0; i < n; i++)
        {
            cout << Heap[i] << " ";
        }
        cout << endl<<endl;
    }
    };
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值