学习堆小结
个人信息:就读于燕大本科软件工程专业 目前大三;
本人博客:百度搜索“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; } }