C++模板实现堆

来源:互联网 发布:c语言贪吃蛇游戏代码 编辑:程序博客网 时间:2024/06/17 08:14

堆是一种特殊类型的二叉树,具有以下两个性质:
1. 每个节点的值大于/小于(最大堆/最小堆)等于其每个子节点的值
2. 该数完全平衡,最后一层的叶子都处于最左侧的位置

本文以最大堆为例子,实现堆的插入与删除操作.其中,堆的插入操作总是在最后的位置,删除操作总是在开头的位置.有些与队列的先进先出相似.
代码实现如下:
其中,利用数组来实现堆,数组的下标天然的可以对应堆的层次结构.若父节点下标为i,则左右子节点下标必然为2*i+1与2*i+2.
堆的插入总是在最后位置,插入后,对该位置进行上移交换,直到满足堆特性为止.删除时,总是删除根节点数据,然后将最后节点数据放入根节点,从根节点开始做向下交换,直到满足堆特性为止.

#ifndef _HEAP_H_#define _HEAP_H_#include "Constant.h"template <class T>struct HeapNode{    T data;                 //data};template <class T, unsigned int capacity>class Heap{public:    Heap();    ~Heap();    void AddElem(T value);    void deleteElem(T &value);    bool isFull();    bool isEmpty();private:    HeapNode<T>** heapArray;    unsigned int elemNum;};#endif
#include "Heap.h"template <class T, unsigned int capacity>Heap<T, capacity>::Heap(){    elemNum = 0;    heapArray = new HeapNode<T>*[capacity];}template <class T, unsigned int capacity>Heap<T, capacity>::~Heap(){    if (elemNum > 0)    {        for (int i = 0; i < elemNum; i++)        {            delete heapArray[i];            heapArray[i] = NULL;        }    }    if (NULL != heapArray)    {        delete[] heapArray;        heapArray = NULL;    }    elemNum = 0;}template <class T, unsigned int capacity>bool Heap<T, capacity>::isEmpty(){    bool result = false;    if (0 == elemNum)    {        result = true;    }    else    {        result = false;    }    return result;}template <class T, unsigned int capacity>bool Heap<T, capacity>::isFull(){    bool result = false;    if (capacity == elemNum)    {        result = true;    }    else    {        result = false;    }    return result;}template <class T, unsigned int capacity>void Heap<T, capacity>::AddElem(T value){    if (isFull())    {        //Do nothing    }    else    {        HeapNode<T>* node = new HeapNode<T>();        node->data = value;        if (isEmpty())        {            heapArray[0] = node;            elemNum++;        }        else        {            heapArray[elemNum] = node;            int parentIndex = (elemNum - 1) / 2;            int childIndex = elemNum;            while (parentIndex >= 0)   //has parent            {                bool hasSwap = false;                if (heapArray[childIndex]->data > heapArray[parentIndex]->data)                {                    int temp = heapArray[parentIndex]->data;                    heapArray[parentIndex]->data = heapArray[childIndex]->data;                    heapArray[childIndex]->data = temp;                    hasSwap = true;                }                if (!hasSwap)                {                    break;                }                else                {                    childIndex = parentIndex;                    parentIndex = (parentIndex - 1) / 2;                }            }            elemNum++;        }    }    return;}template <class T, unsigned int capacity>void Heap<T, capacity>::deleteElem(T& value){    if (isEmpty())    {        //Do nothing    }    else    {        value = heapArray[0]->data;        //Copy last value to root, delete last memory        heapArray[0]->data = heapArray[elemNum - 1]->data;        delete heapArray[elemNum - 1];        heapArray[elemNum - 1] = NULL;        elemNum--;        //move deap        int index = 0;        while (index * 2 + 1 < elemNum)        {            bool hasSwap = false;            if (index * 2 + 2 < elemNum)  //Both has left and right            {                //compare 3 elem, index, index*2+1 & index*2+2                if (heapArray[index * 2 + 1]->data > heapArray[index * 2 + 2]->data)   //Left is big                {                    if (heapArray[index]->data < heapArray[index * 2 + 1]->data)                    {                        //swap                        int temp = heapArray[index]->data;                        heapArray[index]->data = heapArray[index * 2 + 1]->data;                        heapArray[index * 2 + 1]->data = temp;                        hasSwap = true;                        index = index * 2 + 1;                    }                    else                    {                        break;                    }                }                else  //Right is big                {                    if (heapArray[index]->data < heapArray[index * 2 + 2]->data)                    {                        //swap                        int temp = heapArray[index]->data;                        heapArray[index]->data = heapArray[index * 2 + 2]->data;                        heapArray[index * 2 + 2]->data = temp;                        hasSwap = true;                        index = index * 2 + 2;                    }                    else                    {                        break;                    }                }            }            else  //only has left            {                //compare 2 elem, index & index*2+1, index*2+1 must leaf node, after compare, no need loop                if (heapArray[index]->data < heapArray[index * 2 + 1]->data)                {                    int temp = heapArray[index]->data;                    heapArray[index]->data = heapArray[index * 2 + 1]->data;                    heapArray[index * 2 + 1]->data = temp;                    break;                }                else                {                    break;                }            }            if (!hasSwap)            {                break;            }        }    }    return;}
0 0