C++实现最小堆(binary heap)

来源:互联网 发布:新淘宝店铺开了没人买 编辑:程序博客网 时间:2024/05/01 17:26

闲来无事,用C++实现了最小堆。

用到了模板类泛型编程,用数组实现的最小堆。

BinHeap.h中的声明:

template<class Type>class BinHeap{public:BinHeap(void);~BinHeap(void);void MakeEmpty();void Insert(const Type& x);Type FindMin();void DeleteMin();int IsEmpty();int IsFull();private:int Capacity;int Size;Type Elements[COUNT];};
其中Capacity是堆的容量,在数值上等于COUNT -1,因为堆的根从数组Elements[1]开始,Elements[0]留着,用作标记。

下面是全部代码:

BinHeap.h

#pragma once#include <stdexcept>using std::runtime_error;#define COUNT 21#defineMIN 0template<class Type>class BinHeap{public:BinHeap(void);~BinHeap(void);void MakeEmpty();void Insert(const Type& x);Type FindMin();void DeleteMin();int IsEmpty();int IsFull();private:int Capacity;int Size;Type Elements[COUNT];};template<class Type>BinHeap<Type>::BinHeap(void):Capacity(COUNT-1),Size(0){Elements[0] = MIN;}template<class Type>BinHeap<Type>::~BinHeap(void){}template<class Type>void BinHeap<Type>::MakeEmpty(){for (int i=0;i<COUNT;i++){Elements[i] = NULL;}Size = 0;}template<class Type>int BinHeap<Type>::IsEmpty(){return Size==0;}template<class Type>int BinHeap<Type>::IsFull(){return Size == Capacity;}template<class Type>Type BinHeap<Type>::FindMin(){if (Size>0){return Elements[1];}return NULL;}template<class Type>void BinHeap<Type>::Insert(const Type& x){if (IsFull()){runtime_error("Heap is Full!!!");}else{Size++;int tmpSize = Size;//Type tmpX = x;while (Elements[tmpSize/2]>x){Elements[tmpSize] = Elements[tmpSize/2];tmpSize/=2;}Elements[tmpSize] = x;}}template<class Type>void BinHeap<Type>::DeleteMin(){int i,child;Type LastElement;if (IsEmpty()){runtime_error("Heap is Empty!!!");}else{LastElement = Elements[Size--];//Be careful of Size--.for (i =1;i*2<=Size;i = child){child = i * 2;if (child!=Size&&Elements[child+1]<Elements[child]){child++;}if (LastElement > Elements[child]){Elements[i] = Elements[child];}else{break;}}Elements[i] = LastElement;}}
BinHeap.cpp 中是空的,就包含两个最基本的include。原因后面解释。

测试代码:

// MinHeap.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "BinHeap.h"#include <iostream>using std::cout;using std::endl;int _tmain(int argc, _TCHAR* argv[]){BinHeap<int> bh;for (int i=0;i<20;i++){int tmp = i+1;bh.Insert(tmp);}cout<<"the min element is "<<bh.FindMin()<<endl;for (int i=0;i<4;i++){bh.DeleteMin();}cout<<"the min element is "<<bh.FindMin()<<endl;getchar();return 0;}

亲测能跑,用的IDE是vs2010.

解释一下为什么把成员函数的定义也放到了头文件中:


因为本代码用的是模板类编程,而当下很多编译器都不再支持模板类编程的声明和实现分开。即 如果把函数实现放在cpp文件里,用main函数测试的时候会出现提示

public: __thiscall BinHeap<int>::BinHeap<int>(void)" (??1?$Compare@H@@QAE@XZ) 无法进行初始化。

也许很久以前是支持的,但是至少vs2008和vs2010是不支持的。

所以只能把成员函数的实现也放到头文件里,就ok了~




原创粉丝点击