数据结构之最小堆的实现C++版

来源:互联网 发布:文件压缩linux 编辑:程序博客网 时间:2024/06/06 07:44

数据结构之最小堆的实现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 oncetemplate<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("整理为最小堆:\n");        for (int i = 0;i < 6;i++) {            printf("%d\n",p[i]);        }    }    system("pause");    return 0;}
复制代码