二叉堆【数据结构】

                                                二叉堆

 

一、介绍

二叉堆是完全二元树或者近似完全二元树,按照数据的排列方式可以分为两种:最大堆和最小堆。

最大堆:父节点的键值总是大于或等于任何一个子节点的键值。

最小堆:父节点的键值总是小于或等于任何一个子节点的键值。

 

二、实现原理

1、二叉堆一般使用数组实现,如果从索引1开始存放元素,那么

(1)i 的左孩子是2*i

(2)i 的右孩子是2*i+1

(3)i 的父节点 i/2

2、插入操作(最大堆)

当向最大堆中添加数据时,先将数据加入最大堆的最后(即数组中最后一个元素的下一个位置),然后尽可能把这个元素往上挪,直到挪不动为止。

3、删除操作(最大堆)

当从最大堆中删除数据时,先删除该数据,然后用最大堆中最后一个元素插入这个空位,然后把这个空位尽量向下挪,直到重新变为最大堆。

注意:最小堆相比最大堆的实现只需改动大小关系即可。

 

三、C++实现(基于数组)

最大堆

//最大堆 

#include

using namespace std;

template 
class MaxHeap{
	private:
		T *heap;//数据
		int capacity;//总的容量
		int size;//实际容量
		
		void down(int start,int end);//最大堆向下调整算法
		void up(int start);//最大堆向上调整算法
		
	public:
		MaxHeap();
		MaxHeap(int capacity); 
		~MaxHeap();
		int getIndex(T data);//返回data在二叉堆中的索引
		bool remove(T data);//删除最大堆中的data
		bool insert(T data);//将data插入二叉堆中
		void print();//打印二叉堆 
}; 

//构造函数 
template
MaxHeap::MaxHeap(int capacity)
{
	this->capacity=capacity;
	this->size=0;
	heap=new T[this->capacity];
} 

template
MaxHeap::MaxHeap()
{
	new (this)MaxHeap(30);
} 

//析构函数
template
MaxHeap::~MaxHeap()
{
	size=capacity=0;
	delete[] heap;
}
 
//返回data在二叉堆的索引位置,如果不存返回-1 
template
int MaxHeap::getIndex(T data)
{
	for(int i=1;i<=size;i++)
	  if(heap[i]==data)
	    return i;
	return -1;
}

//最大堆的向上调整算法 
template
void MaxHeap::up(int start)//start上调的开始位置 
{
	int c=start;
	T temp=heap[c];
	int p=c/2;//p是c的父节点
	while(p>0)
	{
		if(temp<=heap[p])
		  break;//上调结束
		else
		{
			heap[c]=heap[p];
			c=p;
			p=p/2;
		} 
	}
	heap[c]=temp; 
}

//插入值为data的元素 
template
bool MaxHeap::insert(T data)
{
	if(size==capacity)//堆已满,添加失败,返回false 
	  return false;
	heap[++size]=data;//将数据插在最后
	up(size);//上调元素 
	return true; 
}

/*
最大堆的向下调整算法 
start:被下调节点的起始位置
end:数组的最后一个元素的位置 
*/ 

template
void MaxHeap::down(int start,int end)
{
	int c=start;//c表示当前结点的位置 
	T temp=heap[c];//当前结点的值 
	int l=2*c;//c的左孩子
	//进行下调
	while(l<=end)
	{
		// l是左孩子,l+1是右孩子
		if(l=heap[l])//下调结束 
		  break; 
		else
		{
			heap[c]=heap[l]; 
			c=l;
			l=l*2;
		}
	}
	heap[c]=temp; 
}

//删除值为data的元素 
template
bool MaxHeap::remove(T data)
{
	//获取data在数组中的索引
	int index=getIndex(data);
	if(index==-1)//未找到 ,删除失败,返回false 
	  return false;
	heap[index]=heap[size--];//用最后元素填补index位置
	down(index,size);//从index位置开始自上而下调整为最大堆 
	return true;//删除失败 
}

//打印二叉堆 
template
void MaxHeap::print()
{
	if(size==0)
	  cout<<"堆为空!";
	for(int i=1;i<=size;i++)
	  cout< *tree=new MaxHeap;
	while(1)
	{
		cout<<"1.插入元素\n2.删除元素\n3.打印最大堆\n4.退出\n";
		int op;
		cin>>op;
		if(op==1)
		{
			int e;
			cout<<"输入元素值:";
			cin>>e;
			bool flag=tree->insert(e);
			cout<<"---------------"<>e;
			bool flag=tree->remove(e);
			cout<<"---------------"<print();
			cout<<"---------------"<

 

最小堆

//最大堆 

#include

using namespace std;

template 
class MaxHeap{
	private:
		T *heap;//数据
		int capacity;//总的容量
		int size;//实际容量
		
		void down(int start,int end);//最大堆向下调整算法
		void up(int start);//最大堆向上调整算法
		
	public:
		MaxHeap();
		MaxHeap(int capacity); 
		~MaxHeap();
		int getIndex(T data);//返回data在二叉堆中的索引
		bool remove(T data);//删除最大堆中的data
		bool insert(T data);//将data插入二叉堆中
		void print();//打印二叉堆 
}; 

//构造函数 
template
MaxHeap::MaxHeap(int capacity)
{
	this->capacity=capacity;
	this->size=0;
	heap=new T[this->capacity];
} 

template
MaxHeap::MaxHeap()
{
	new (this)MaxHeap(30);
} 

//析构函数
template
MaxHeap::~MaxHeap()
{
	size=capacity=0;
	delete[] heap;
}
 
//返回data在二叉堆的索引位置,如果不存返回-1 
template
int MaxHeap::getIndex(T data)
{
	for(int i=1;i<=size;i++)
	  if(heap[i]==data)
	    return i;
	return -1;
}

//最小堆的向上调整算法 
template
void MaxHeap::up(int start)//start上调的开始位置 
{
	int c=start;
	T temp=heap[c];
	int p=c/2;//p是c的父节点
	while(p>0)
	{
		if(temp>=heap[p])//最大堆是<= 
		  break;//上调结束
		else
		{
			heap[c]=heap[p];
			c=p;
			p=p/2;
		} 
	}
	heap[c]=temp; 
}

//插入值为data的元素 
template
bool MaxHeap::insert(T data)
{
	if(size==capacity)//堆已满,添加失败,返回false 
	  return false;
	heap[++size]=data;//将数据插在最后
	up(size);//上调元素 
	return true; 
}

/*
最小堆的向下调整算法 
start:被下调节点的起始位置
end:数组的最后一个元素的位置 
*/ 

template
void MaxHeap::down(int start,int end)
{
	int c=start;//c表示当前结点的位置 
	T temp=heap[c];//当前结点的值 
	int l=2*c;//c的左孩子
	//进行下调
	while(l<=end)
	{
		// l是左孩子,l+1是右孩子
		if(lheap[l+1])//最大堆是heap[l]
bool MaxHeap::remove(T data)
{
	//获取data在数组中的索引
	int index=getIndex(data);
	if(index==-1)//未找到 ,删除失败,返回false 
	  return false;
	heap[index]=heap[size--];//用最后元素填补index位置
	down(index,size);//从index位置开始自上而下调整为最大堆 
	return true;//删除失败 
}

//打印二叉堆 
template
void MaxHeap::print()
{
	if(size==0)
	  cout<<"堆为空!";
	for(int i=1;i<=size;i++)
	  cout< *tree=new MaxHeap;
	while(1)
	{
		cout<<"1.插入元素\n2.删除元素\n3.打印最小堆\n4.退出\n";
		int op;
		cin>>op;
		if(op==1)
		{
			int e;
			cout<<"输入元素值:";
			cin>>e;
			bool flag=tree->insert(e);
			cout<<"---------------"<>e;
			bool flag=tree->remove(e);
			cout<<"---------------"<print();
			cout<<"---------------"<

 

你可能感兴趣的:(数据结构__堆相关)