优先队列(堆序结构)

/*
二叉堆:
结构性质:
    是一个被完全填满的二叉树,有可能的例外是在底层,底层上的元素从左侧到右侧填入。
	这样的树称为完全二叉树。(copmlete binary tree)
	容易证明一颗高为h的完全二叉树有2^h到2^(h+1) - 1个节点。
	因为完全二叉树很有规律,所以它可以用一个数组表示,不需要指针。对于数组中任一位置i上的元素,
	其左儿子在位置2i上,其右儿子在左儿子后的单元2i+1中,它的父亲则在位置i/2上。因此,不仅指针这里不需要,
	而且遍历该树锁需要的操作也极简单,在大部分计算机上运行很可能非常快。

堆序性质:
    使操作被快速执行的性质是堆序性。由于我们想要快色地找出最小元,因此最小元应该在根上。
	如果我们考虑任意子树也应该是一个堆,那么任意结点就应该小于它的所有后裔。


*/
#include <iostream>
using namespace std;
template<typename T>
class HeapStruct
{
public:
	int capacity; //容量
	int size;     //现在拥有的元素数
	T *data;    //元素集	
public:
	HeapStruct(){data = NULL;size = 0;capacity = 0;}
public:
	HeapStruct* Initialze(int MaxElements,HeapStruct *H);
	void Insert(T x);
	void DeleteMin();
	void Print();
};
//堆结构初始化
template<typename T>
HeapStruct<T> *HeapStruct<T>::Initialze(int MaxElements,HeapStruct<T> *H)
{
	//H = new HeapStruct();
	//if(H == NULL)
	//	cout << "内存分配失败"<<endl;
	H->data = new T[MaxElements];
	if(H->data == NULL)
		cout <<"内存分配失败"<<endl;
	H->capacity = MaxElements;
	H->size = 0;
	H->data[0] = 0;
	return H;
}
//堆序列插入
//最小结点为顶点
template<typename T>
void HeapStruct<T>::Insert(T x)
{
	int i;
	if(this->size == this->capacity)
	{
		cout << "full"<<endl;
		return ;
	}
	for(i = ++this->size;this->data[i/2] > x;i/=2)
	{
		this->data[i] = this->data[i/2];
	}
	this->data[i] = x;
}
//堆序列删除最小结点
template<typename T>
void HeapStruct<T>::DeleteMin()
{
	int i,child;
	T Mindata,LastData;
	if(this->size == 0)
	{
		cout <<"堆序列为空"<<endl;
		return ;
	}
	Mindata = this->data[1];
	LastData = this->data[this->size--];
	for(i = 1; i*2<=this->size;i=child)
	{
		child = i*2;
		if(child != this->size && this->data[child+1] < this->data[child])
		{
			child++;
		}
		if(LastData > this->data[child])
			this->data[i] = this->data[child];
		else
			break;
	}
	this->data[i] = LastData;
}
//遍历
template<typename T>
void HeapStruct<T>::Print()
{
	int i,child;
	for(i = 1;i<=this->size;i++)
	{
		cout << this->data[i] << " ";
	}
	cout << endl;
}
//test
int main()
{
	HeapStruct<int> *h = new HeapStruct<int>();
	h = h->Initialze(10,h);
	//0 1 2 5 4 3 9 6 10 7 8
	for(int i = 10;i>0;i--)
	{
		h->Insert(i);
	}
	h->Print();
	h->DeleteMin();
	h->Print();
	h->DeleteMin();
	h->Print();
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值