zoukankan      html  css  js  c++  java
  • 数据结构之最小堆的实现C++版

    完全二叉树之所以用数组的方式存在,在于他的一个特性 若子节点为i,则父节点为(i-1)/2,注意c++特性,该结果肯定是个整数。

    若父节点为j,则子节点必为2*j+1;则在数组里面可以非常方便的通过下标去获取。

    建堆的核心思想:

      堆在index的值为heap[index],然后其两个孩子的值边可求得,左孩子为heap[index*2+1],右孩子为heap[index*2+2]。

    首先比较左边孩子与右边孩子,获取较小值的孩子,然后让heap[index]与值较小的孩子进行比较。若值小则交换值,并且移动index到值较小孩子的位置,否则退出调整。

    下面看代码,有注释:

    #pragma once
    template<class T>
    class JBMinHeap
    {
    private:
        //申请堆空间
        T *_minHeap = NULL;
        int _index,_maxSize;
    public:
        JBMinHeap(int maxSize) {
            _maxSize = maxSize;
            _minHeap = new T[_maxSize];
            _index = -1;
        }
        JBMinHeap(JBMinHeap &h) {
            _index = h._index;
            _maxSize = h._maxSize;
            _minHeap = new T[_maxSize];
            for (int i = 0;i<_maxSize) {
                *_minHeap[i] = *h._minHeap[i];
            }
        }
        ~JBMinHeap() {
            delete[]_minHeap;
        }
        //获取整个最小堆的头部指针
        T * getMinHeap() {
            return _minHeap;
        }
        //判断堆是不是空的
        bool isEmpty() {
            return _index == -1;
        }
        bool add(T x) {
            if (isFull()) {
                return false;
            }
            _index++;
            _minHeap[_index] = x;
            return true;
        }
        bool isFull() {
            return _index == _maxSize;
        }
        //堆进行向下调整
        void adjustDown(int index);
        //队进行向上调整
        void adjustUp(int index);
        //建堆运算
        void createMinHeap() {
            if (isEmpty()) {
                return;
            }
            for (int i = (_index-1)/2;i >-1;i--) {//直接从倒数第二层 逐层向下调整
                adjustDown(i);
            }
        }
    };
    template<class T>
    void JBMinHeap<T>::adjustDown(int index) {
        if (isEmpty()) {
            return;
        }
        while (index<_index)
        {
            T temp = _minHeap[index];//将当前索引的位置的值保存下来
            int oneC = 2 * index + 1;//获取到两个孩子的位置
            int twoC = 2 * index + 2;
            if (oneC == _index) {//若第一个孩子是整个堆最后一个位置 则直接执行交换操作并结束执行
                    _minHeap[index] = _minHeap[oneC];
                    _minHeap[oneC] = temp;
                    return;
            }
            if (twoC >_index) {//如果第二个孩子的索引位置越界 结束执行
                return;
            }
            if (_minHeap[oneC] <= _minHeap[twoC]) {//正常情况的数据交互执行
                if (temp > _minHeap[oneC]) {
                    _minHeap[index] = _minHeap[oneC];
                    _minHeap[oneC] = temp;
                    index = oneC;
                }
                else {//如果该处索引值已经是比两个孩子小 则结束循环
                    index = _index;
                }
            }
            else 
            {
                if (temp > _minHeap[twoC]) {
                    _minHeap[index] = _minHeap[twoC];
                    _minHeap[twoC] = temp;
                    index = twoC;
                }
                else 
                {
                    index = _index;
                }
            }
        }
    }
    template<class T>
    void JBMinHeap<T>::adjustUp(int index) {
        if (index > _index) {//大于堆的最大值直接return
            return;
        }
        while (index>-1)
        {
            T temp = _minHeap[index];
            int father = (index - 1) / 2;
            if (father >= 0) {//若果索引没有出界就执行想要的操作
                if (temp < _minHeap[father]) {
                    _minHeap[index] = _minHeap[father];
                    _minHeap[father] = temp;
                    index=father;
                }
                else {//若果已经是比父亲大 则直接结束循环
                    index = -1;
                }
            }
            else//出界就结束循环
            {
                index = -1;
            }
        }
    }

    主程序:

    #include "stdafx.h"
    #include"stdlib.h"
    #include"JBQueue.h"
    #include"JBStack.h"
    #include"JBBinaryTree.h"
    #include"JBMinHeap.h"
    
    int main()
    {
        {
            JBMinHeap<int> jb(10);
            jb.add(20);
            jb.add(18);
            jb.add(19);
            jb.add(13);
            jb.add(42);
            jb.add(5);
            jb.createMinHeap();
            int *p=jb.getMinHeap();
            printf("整理为最小堆:
    ");
            for (int i = 0;i < 6;i++) {
                printf("%d
    ",p[i]);
            }
        }
        system("pause");
        return 0;
    }

  • 相关阅读:
    Devrama Slider
    全栈开发必备的10款 Sublime Text 插件
    经典网页设计:使用颜色滤镜效果的20个网站
    Nibbler – 免费的网站测试和指标评分工具
    使用 HTML5 Canvas 绘制出惊艳的水滴效果
    Qt4 和 Qt5 模块的分类
    设计Qt风格的C++API
    Qt属性系统
    Qt实现艺术字效果
    Qt中容器类应该如何存储对象(最好使用对象指针类型,如:QList<TestObj*>,而不要使用 QList<TestObj> 这样的定义,建议采用 智能指针QSharedPointer)
  • 原文地址:https://www.cnblogs.com/enjoyall/p/6028697.html
Copyright © 2011-2022 走看看