最小堆的实现


 

/**

这边实现的是最小堆,最小堆是这样定义的,首先堆是一棵完全二叉树,每一个节点都有一个权值,满足的条件是,父节点的权值总是大于等于子节点的权值

**/

#include <iostream>

using namespace std;


//最小堆类的定义如下

template <class T>

class MinHeap

{

private:

   T * nodes;                                                     //用来存放二叉树的每一个节点的数组

   int currentsize;                                             //当前堆中有的元素个数

   int maxsize;                                                  //堆中允许存放的最大的元素个数

public:

void makeHeap(int n);                                     //建堆,创建一个空堆

MinHeap<T> & insert(T & t);                            //向堆中插入一个元素,保持堆得性质不变

MinHeap<T>&  del(T& t);                                 //从堆中删除最下的那个元素保持堆的性质不变,同时将这个元素放到t中

T & get(int index )

{

            return nodes[index] ;

}

};


template <class T> 

void MinHeap<T> ::makeHeap(int maxsize)

{

    nodes = new  T[maxsize+1];                           //这边是一个小的技巧,开辟的一个数组的大小比最大元素个数多一个,这样堆中                                                                               //元素就是从下标1开始的,不需要进行复杂的判断了

this->maxsize = maxsize;           

this->currentsize = 0;

}


/**

向堆中插入一个元素,基本的算法是这样的,首先将这个元素添加到数组的最后,然后沿着树向根方向一直查找直到这个元素应该存放的位置为止

**/

template <class T>

MinHeap<T> & MinHeap<T>::insert(T & t)          

{

this ->currentsize ++;

nodes[currentsize] = t;

int index = this ->currentsize ;

while(index >1 && nodes[index] < nodes[index/2])

{

       nodes [ index ] = nodes[index/2];

  index = index / 2 ;

}

nodes [index ] = t;

return * this;

}


/**

删除的过程和插入的过程类似,只不过是逆过来的,从根向叶方向判断,直到找到了合适的位置。

**/

template <class T>

MinHeap<T> & MinHeap<T>::del(T&t )

{

    t = nodes[1] ;

T tem = nodes[this->currentsize] ;                                                                   //将最后一个元素取出来,然后放到根上                                                                                                                                    //(nodes[1])接着调整它的位置

this ->currentsize --;

    int index = 1;                                                                                                //这个是放置tem元素的位置的下标。

int  sonindex = 2;                                                                                             //这个变量是用来存放较小元素的子节点的下标的

while(sonindex <= this ->currentsize ) 

{

if(sonindex < this ->currentsize &&  nodes[sonindex] > nodes[sonindex+1])  //这边是找出index元素的两个子节点中值较小                                                                                                                            //的那个

sonindex ++;

if(tem < nodes[sonindex])

      break;

 nodes[index] = nodes[sonindex]; 

 index = sonindex;

 sonindex *= 2;

}

nodes [index] = tem;

return * this;

}


int main()

{

MinHeap<int> heap ;

heap.makeHeap(10);

for(int i =0 ;i < 6; i ++)

heap.insert(i);

for(int i = 1;i <= 6 ;i ++)

cout << heap.get(i) << "   " ;

cout << endl;

 

for(int  i = 0 ;i < 6;i ++)

{

int x;

heap.del(x);

cout << x << endl;

}


return 0 ;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值