最小堆 c++源代码

#ifndef _MINHEAP_H
#define _MINHEAP_H

template <class T>
class MinHeap  	//最小堆ADT定义
{
private:
	T* heapArray;		//存放堆数据的数组
	int CurrentSize;	//当前堆中元素数目
	int MaxSize;		//堆所能容纳的最大元素数目
	void BuildHeap();	//建堆
public:
	//构造函数,n表示初始化堆的最大元素数目
	MinHeap(const int n,const T* array, int size);
	//析构函数
	virtual ~MinHeap()
	{
		delete []heapArray;
	}
	//如果是叶结点,返回TRUE
	bool isLeaf(int pos) const; 
	//返回左孩子位置
	int leftchild(int pos) const;
	//返回右孩子位置
	int rightchild(int pos) const; 
	// 返回父结点位置
	int parent(int pos) const; 
	// 删除给定下标的元素
	bool Remove(int pos, T& node);
	//向堆中插入新元素newNode
	bool Insert(const T& newNode);
	//从堆顶删除最小值
	T& RemoveMin();
	//从position向上开始调整,使序列成为堆
	void SiftUp(int position);
	//筛选法函数,参数left表示开始处理的数组下标
	void SiftDown(int left);
};

template<class T>
MinHeap<T>::MinHeap(const int n,const T* array, int size)
{
	if(n<=0||size>n)
		return;
	CurrentSize=0;						
	MaxSize=n;//初始化堆容量为n
	heapArray=new T[MaxSize];//创建堆空间
	//此处进行堆元素的赋值工作
	//要为heapArray数组进行一些赋值,不然
	//无法实现建堆操作,因为CurrentSize为0
	for(int i=0; i<size; i++)
	{
		heapArray[i]=array[i];
	}
	CurrentSize = size;
	BuildHeap();
}

//建堆
template<class T>
void MinHeap<T>::BuildHeap()
{
	//反复调用筛选函数,问题:CurrentSize<2?
	for (int i=CurrentSize/2-1; i>=0; i--)
		SiftDown(i);					
} 

//筛选法函数,参数left表示开始处理的数组下标
template <class T>
void MinHeap<T>::SiftDown(int position)
{
	int i=position;//标识父结点
	//此时j不一定是关键值较小的子结点,
	//但是希望它标识关键值较小的子结点。
	int j=2*i+1;		
	T	temp=heapArray[i];//保存父结点
	//过筛
	while(j<CurrentSize){
	    if((j<CurrentSize-1)&&(heapArray[j]>heapArray[j+1]))
		{
			//while第一次循环时,如果进入,比较左结点和右结点的值
			//如果左结点的值大于右结点的值则,j指向数值较小的子结点
			j++;
		}			
		if(temp>heapArray[j]){
			heapArray[i]=heapArray[j];
			i=j;
			j=2*j+1;//向下继续
		}//end if
		else
			break;
	}//end if
	heapArray[i]=temp;
}

//如果是叶结点,返回TRUE
template<class T>
bool MinHeap<T>::isLeaf(int pos) const
{
	return (pos>=CurrentSize/2)&&(pos<CurrentSize);
}

//返回左孩子位置
template<class T>
int MinHeap<T>::leftchild(int pos) const
{
	return 2*pos+1;//返回左孩子位置
}

//返回右孩子位置
template<class T>
int MinHeap<T>::rightchild(int pos) const
{
	return 2*pos+2;//返回右孩子位置
}

// 返回父结点位置
template<class T>
int MinHeap<T>::parent(int pos) const  
{
	return (pos-1)/2;//返回父结点位置
}

//向堆中插入新元素newNode
template <class T>
bool MinHeap<T>::Insert(const T& newNode)
{
	if(CurrentSize == MaxSize)//堆空间已经满
		return false;
	heapArray[CurrentSize]=newNode;
	SiftUp(CurrentSize);//向上调整
	CurrentSize++;
}

//从position向上开始调整,使序列成为堆
template<class T>
void MinHeap<T>::SiftUp(int position) 
{
	int temppos=position;
	T temp=heapArray[temppos];
	//请比较父子结点直接swap的方法
	while((temppos>0)&&(heapArray[parent(temppos)]>temp))   
	{
		heapArray[temppos]=heapArray[parent(temppos)];
		temppos=parent(temppos);
	}
	heapArray[temppos]=temp;
}

//从堆顶删除最小值
template<class T>
T& MinHeap<T>::RemoveMin()
{

	if(CurrentSize==0)
	{
		//空堆
		cout<<"Can't Delete";
		exit(1);
	}
	else
	{
		//交换堆顶和最后一个元素
		swap(0,--CurrentSize);
		if(CurrentSize>1)  // <=1就不要调整了  
			//从堆顶开始筛选
			SiftDown(0);
		return heapSize[CurrentSize];
	}//end else
}

// 删除给定下标的元素
template<class T>
bool MinHeap<T>::Remove(int pos, T& node)
{// 删除给定下标的元素
	if((pos<0)||(pos>=CurrentSize))
		return false;
	//指定元素置于最后
	T temp=heapArray[pos];
	heapArray[pos]=heapArray[--CurrentSize];	
	SiftUp(pos);//上升筛
	SiftDown(pos);//向下筛,不是SiftDown(0);	
	node=temp;
	return true;
}

#endif


调用

#include "MinHeap.h"
#include <stdio.h>

void main()
{
	int array[10]={10,9,8,7,6,5,4,3,2,1};
	MinHeap<int>* heap = new MinHeap<int>(20,array,10);

	int node = 4;
	heap->Insert(node);

	delete heap;
	heap = NULL;
}


//参考北京大学张铭ppt

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值