学习堆小结

56 篇文章 0 订阅
36 篇文章 1 订阅

学习堆小结

个人信息:就读于燕大本科软件工程专业 目前大三;

本人博客:百度搜索“cqs_2012”即可;

个人爱好:酷爱数据结构和算法,希望将来搞科研为人民作出自己的贡献;

博客内容:数据结构里的堆(大顶堆或小顶堆;

知识选自:个人对堆长时间的理解和应用,故总结与此;

博客时间:2014-3-24

 

  • 引言

学过堆排序以后,但是一直没对堆没有认真的总结过,知识点很散,理解不够深刻,相信这一次对堆有真正的了解。本人博客若有错误之处,还望大神及时指出,谢谢大家一直对本人的支持与关注。

  • 总结

本人第一次接触堆是堆排序,然后发现这个排序算法很好,算法很快,便自己总结并实现了一下,若果有兴趣,请奔本人博客堆排序;

先学习最大堆吧,在堆排序算法里,我们用的是最大堆,堆排序有两个步骤,第一步是建堆,第二步是维护堆。对于第一步来说,我以前的博客里是这样做的,

数据存在一个数组里,从后往前依次取数据并插入堆中,并进行维护,每次都插入堆的根上,然后下溯的方法来维护堆得性质;算法如下

		for(int i=length/2-1;i>=0;i--)
		{
			Heap_downcast(data,i,length);		
		}

堆的下溯操作:

那么下溯是怎么实现的呢?算法如下

// template function for delete
template<class T> 
void Heap_downcast(T *data,int i,const int length)
{
	if(data != NULL && length >= 0)
	{
		T max ;
		// have two children
		while(i*2+2 <length)
		{
			max = data[i];
			if(max >= data[i*2+1] && max >= data[2*i+2])
				break;
			// right child bigger 
			if( data[i*2+2]>data[2*i+1] && data[i*2+2]>max)
			{
				max = data[i*2+2];
				data[i*2+2] = data[i];
				data[i] = max;
				i = i*2+2;
			}
			// left child bigger
			else if( data[i*2+1] >= data[2*i+2] && data[i*2+1]>max )
			{
				max = data[i*2+1];
				data[i*2+1] = data[i];
				data[i] = max;
				i = i*2+1;		
			}			
		}
		// have one child
		if(i*2+1 < length)
		{
			if(data[i*2+1]>data[i])
			{
				max = data[i*2+1];
				data[i*2+1] = data[i];
				data[i] = max;
			}
		}
	}
	else 
	{
		cout<<"exception of input Heap_downcast"<<endl;
	}
}

 

在这里我介绍另一种建堆的方法,就是把存在数组中的数据从前向后依次取数据插入堆的叶子(尾部)上,然后上溯来维护堆的性质;算法如下

		way2: for heap upcast;
		for(int i=0;i<length;i++)
		{
			Heap_upcast(data,i,length);
		}

堆的上溯操作:

那么上溯的算法是怎么实现的呢?算法如下

// template function for insert
template<class T> 
void Heap_upcast(T *data,int i,const int length)
{
	if(data != NULL && length >= 0)
	{
		T max ;
		// have two children
		while( (i-1)/2 >= 0 )
		{
			max = data[i];
			if(max <= data[(i-1)/2])
				break;
			// child bigger, and go up
			else 
			{
				data[i] = data[(i-1)/2];
				data[(i-1)/2] = max;
				
				i = (i-1)/2;
			}		
		}
	}
	else 
	{
		cout<<"exception of input Heap_downcast"<<endl;
	}
}


通过这样灵活运用堆的各种操作,我们就能很好的理解堆了;比如我们已经很好的可以在堆的末尾插入元素(如果堆顶为空,也可以很好的在堆顶插入元素)
,那么如果删除堆中的一个元素呢?我们怎么办呢?,我们会用到下溯方法,算法如下

// function:delete elem from heap
template<class T> 
void heap_delete_elem(T *data,int i,const int length)
{
	if(data != NULL && i>= 0 && i<length)
	{
		// change two data
		T d = data[i] ;
		data[i] = data[length-1] ;
		data[length-1] = d ;
		// downcast for the data[i]
		Heap_downcast(data,i,length-1);
	}
	else
	{
		// for deal exception
		cout<<"exception of input Heap_downcast"<<endl;
	}
}


 


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值