数据结构(树)

114 阅读2分钟

/*	堆(完全二叉树) 
*/ 
#include<bits/stdc++.h>
using namespace std;
typedef struct Heap{
	int *data;
	int size;
	int maxsize;
}*Maxheap,*Minheap;

Maxheap Heap_init(int maxsize)
{
	Maxheap h = (Maxheap)malloc(sizeof(struct Heap));
	h->data = (int *)malloc((maxsize+1)*sizeof(int));
	h->maxsize = maxsize;
	h->size = 0;
	h->data[0] = 1e8;		//定义哨兵为大于堆中所有元素的值
	return h; 
}
/*堆的建立方法1 
	将n个元一个个插入, 时间代价 o(NlogN) 
*/ 
void Maxheap_insert(Maxheap h,int e)
{
	int i;
	i = ++h->size;
	while(h->data[i/2] < e)//向下过滤节点 比交换节点要快 
	{
		h->data[i] = h->data[i/2];
		i/=2;			 
	}
	h->data[i] = e;
}
/*堆的建立方法2 
	从最后一个非叶节点(n/2) 开始到根节点 
*/
void sift(Maxheap h,int i)
{
	int tmp = h->data[i];
	int cld;
	for(;i*2<=h->size;i=cld)
	{
		cld = i*2;
		if((cld+1)<=h->size && h->data[cld+1]> h->data[cld])
			cld += 1;
		if(h->data[cld]<=tmp)
			break;
		else
			h->data[i] = h->data[cld];
	}
	h->data[i] = tmp;
} 
// 从最大堆取出元素 
int  Maxheap_delete(Maxheap h)
{
	int res = h->data[1];		  // 取出根节点(最大元素) 
	int tmp = h->data[h->size--];//用最大堆最后一个元素从根节点向上过滤
	int i,cld;
	for(i=1 ; i*2<=h->size ; i = cld) 
	{	
		cld = i*2;
		if( (cld+1)<=h->size && h->data[cld+1]>h->data[cld])
			cld += 1 ;			//选取两个儿子中较大的儿子
		if(tmp >= h->data[cld])
			break;				//parent 比两个cld 都大 就不必移动了
		else h->data[i] = h->data[cld];
	}
	h->data[i] = tmp;
	return res;
}
int main()
{
	Maxheap h = Heap_init(10);
	int lis[6] = {16,12,32,1,343,2};
	//方法1
//	Maxheap_insert(h,10);
//	Maxheap_insert(h,31);
//	Maxheap_insert(h,44);
//	Maxheap_insert(h,18);
//	Maxheap_insert(h,25);
//	Maxheap_insert(h,58);
//	Maxheap_insert(h,518);
//	Maxheap_insert(h,8);
//	for(int i=1;i<=h->size;i++)
//	{
//		//cout<<h->data[i]<<endl;
//	}
	/*
		方法2 
	*/
	for(int i=0;i<6;i++) h->data[i+1] = lis[i];
	h->size = 6;
	for(int i=h->size/2;i>=1;i--) sift(h,i);
	while(h->size>0)
	{
		cout<<Maxheap_delete(h)<<" ";
	}
}