STL Heap
来源:互联网 发布:汽车电脑板维修编程 编辑:程序博客网 时间:2024/05/16 16:17
在《数据结构》的课时学习中,我们知道heap的图其实是一颗完全二叉树,基于其特征,可以用array来存储,且根据其需要,分为大顶堆和小顶堆。然而,在STL中,由于array的缺点(无法动态改变大小),改用vector代替array,并且只供应大顶堆max-heap。
在此又不得不粗略提一下vector容器的实现原理。
Vector容器的数据结构实际就是一段线性连续空间,用迭代器start和finish分别指向连续空间中目前被使用的范围(就好像队列queue的头尾指针一样),就个人认为vector其实是和array几乎一样的存在。但vector为了实现快速的内存分配,在分配空间容量时会比当前所需空间多一些,用于存放新添加的元素;当预留空间用完时,以加倍当前容量的分配策略实现重新分配(事实上容量的重新分配需要“重新配置、元素移动、释放原空间”的过程,事实证明这个策略所变现出来的性能非常好)。然后,在基于array和快速内存分配的基础上,应用了迭代器begin、end和end_of_storage(连续可用空间的尾),提供了首尾标示、大小、容量、空容器、标注([ ])运算等等的机能。
在STL中为堆heap的创建和操作提供了4种算法:make_heap,pop_heap,push_heap和sort_heap。其中:
make_heap:利用区间[first,last)中的元素构造一个heap。
函数原型:void make_heap(first,last)
void make_heap(first,last ,compare_fuction)。
pop_heap: 假定区间[first,last)中已包含一个堆,将first位置和last-1位置上的值交换,重新把[first,last-1)调整为一个堆。
函数原型:void pop_heap(first,last);
void pop_heap(first,last,compare_fuction)。
push_heap: 假定区间[first,last-1)已经包含了一个堆,把区间[first,last)调整为一个堆(从而 把last-1位置上的元素压入堆。
函数原型:void push_heap(first,last);
void push_heap(first,last,compare_fuction).
sort_heap: 对存储在堆中的元素进行排序。
函数原型:void sort_heap(first,last);
void sort_heap(first,last,compare_fuction)
对比之前做过的堆排序的实验,感觉STL中的heap优化并不比教材里面介绍的强多少。想想也应该是,那算法思想是一模一样的,但在代码的实现上,STL中做到了规范化。其次,STL中应用了vector作为heap的底层机制,克服了教材中用array存储空间无法动态改变大小的缺点。其三,STL中关于heap的四个算法都实现了函数重载,虽然STL中关于heap默认调整成的是大顶堆,但却可以让用户利用自定义的compare_fuction函数实现大顶堆或小顶堆。其四,heap的低层机制vector本身就是一个类模板,heap基于vector便实现了对各种数据类型(无论基本数据类型还是用户自定义的数据类型)的堆排(前提是用户自定义的数据类型要提供比较机制compare_fuction函数)。
参考阅读书籍:《STL源码剖析》、《C++Primer中文版》、
《标准模板库自修教程与参考手册:STL进行C++编程》
----------------------------------
最大堆实现
#ifndef MAXHEAP_H
#define MAXHEAP_H
template<class T>
class MaxHeap
{
public:
MaxHeap(T a[], int size,int maxsize=50);
MaxHeap(int maxsize=50);
virtual ~MaxHeap();
void Initialize(T arrays[],int size,int array_size);//用数组对堆重新进行初始化
MaxHeap<T>& Insert( T value);
MaxHeap<T>& DeleteMax(T& value );
bool IsEmpty(){return CurrentSize==0?true:false;};
int Size(){return CurrentSize;}
void Init(T a[]);
private:
void ModifyUp(int start);
void ModifyDown(int start,int end);
private:
T *Data;
int MaxSize;
int CurrentSize;
};
template<class T>
MaxHeap<T>::MaxHeap(T a[], int size,int maxsize)
{
Data=a;
CurrentSize=size;
MaxSize=maxsize;
for( int i=CurrentSize/2;i>=1;i--)
{
ModifyDown(i,CurrentSize);
}
}
//-----------------------------------------------------------------------
template<class T>
void MaxHeap<T>::Initialize(T arrays[],int size,int array_size)
{
if(Data)
delete[] Data;
Data=arrays;
CurrentSize=size;
MaxSize=array_size;
for(int i=CurrentSize/2;i>=1;i--)
{
ModifyDown(i,CurrentSize);
}
}
//-------------------------------------------------------------------------
template<class T>
MaxHeap<T>::MaxHeap(int maxsize)
{
//0号单元不用舍弃,数据从一号单元填入
MaxSize=maxsize;
Data=new T[MaxSize+1];
CurrentSize=0;
}
//-------------------------------------------------------------------------
template<class T>
MaxHeap<T>::~MaxHeap()
{
delete[] Data;
}
//-------------------------------------------------------------------------
template<class T>
MaxHeap<T>& MaxHeap<T>::Insert(T value)
{
if(CurrentSize==MaxSize)
{
cout<<"错误:堆空间已满."<<endl;
throw exception("堆空间已满");
}
Data[++CurrentSize]=value;
ModifyUp(CurrentSize);//重新调整堆
return *this;
}
//-------------------------------------------------------------------------
template<class T>
MaxHeap<T>& MaxHeap<T>::DeleteMax( T& value )
{
if(CurrentSize==0)
{
cout<<"错误:堆空."<<endl;
throw exception("堆空");
}
value=Data[1];
Data[1]=Data[CurrentSize--];
ModifyDown(1,CurrentSize);//重新调整堆
return *this;
}
//-------------------------------------------------------------------------
template<class T>
void MaxHeap<T>::ModifyUp(int start)
{
int i=start;
T x=Data[i];
//当未到达根结点并且start所指节点值大于其父节点时进行移动
while(i!=1&&x>Data[i/2])
{
Data[i]=Data[i/2];//将父节点下移
i/=2;//i指针上移
}
Data[i]=x;
return ;
}
//----------------------------------------------------------------
template<class T>
void MaxHeap<T>::ModifyDown(int start,int end)
{
T x=Data[start];
int c=2*start;
while(c<=end)
{
if(c<end&&Data[c]<Data[c+1]) c++;
if(x>Data[c]) break;
else
{
Data[c/2]=Data[c];//将孩子上移
c*=2;
}//if
}//while
Data[c/2]=x;
}
#endif
------------------------------------------
1.template<class T>
2.class MaxHeap{
3. public:
4. MaxHeap(T a[],int n);
5. MaxHeap(int ms);
6. ~MaxHeap();
7. bool Insert(const T &x);//插入一个元素,如果空返回false,否则返回true
8. bool RemoveMax(T &x);//删除最小的元素,如果空返回false,否则返回true
9. void MakeEmpty();//使堆为空
10. bool IsEmpty();
11. bool IsFull();
12.
13.protected:
14. void FilterDown(const int start,const int endOfHeap);//自顶向下构造堆
15. void FilterUp(const int start);//自底向上构造堆
16. private:
17. T *heap;
18. int maxSize;
19. const int defaultSize;
20. int currentSize;
21.};
22.template<class T>
23.MaxHeap<T>::MaxHeap(int ms):defaultSize(100){
24. maxSize = ms > defaultSize ? ms : defaultSize;
25. heap = new T[maxSize];
26. currentSize = 0;
27.}
28.template<class T>
29.MaxHeap<T>::MaxHeap(T a[],int n):defaultSize(100){
30. maxSize = n > defaultSize ? n : defaultSize;
31. heap = new T[maxSize];
32. currentSize = n;
33. for(int i = 0; i < n; i++)
34. heap[i] = a[i];
35. int curPos = (currentSize - 2) / 2;
36. while(curPos >= 0){
37. FilterDown(curPos,currentSize - 1);
38. curPos--;
39. }
40.}
41.template<class T>
42.MaxHeap<T>::~MaxHeap(){
43. delete []heap;
44.}
45.template<class T>
46.void MaxHeap<T>::FilterDown(const int start,const int endOfHeap){
47. int i = start,j = i * 2 + 1;
48. T temp = heap[i];
49. while(j <= endOfHeap){
50. if(j < endOfHeap && heap[j] < heap[j+1]) j++;
51. if(temp > heap[j]) break;
52. else{
53. heap[i] = heap[j];
54. i = j;
55. j = 2 * i + 1;
56. }
57. }
58. heap[i] = temp;
59.}
60.template<class T>
61.void MaxHeap<T>::FilterUp(const int start){
62. int i = start, j = ( i - 1 ) / 2;
63. T temp = heap[i];
64. while(i > 0){
65. if(temp <= heap[j]) break;
66. else{
67. heap[i] = heap[j];
68. i = j;
69. j = (i - 1) / 2;
70. }
71. }
72. heap[i] = temp;
73.}
74.template<class T>
75.bool MaxHeap<T>::RemoveMax(T &x){
76. if(IsEmpty()){
77. cerr<<"Heap empty!"<<endl;
78. return false;
79. }
80. x = heap[0];
81. heap[0] = heap[currentSize - 1];
82. currentSize--;
83. FilterDown(0,currentSize-1);
84. return true;
85.}
86.template<class T>
87.bool MaxHeap<T>::Insert(const T& x){
88. if(IsFull()) {
89. cerr<<"Heap Full!"<<endl;
90. return false;
91. }
92. heap[currentSize] = x;
93. FilterUp(currentSize);
94. currentSize++;
95. return true;
96.}
97.template<class T>
98.bool MaxHeap<T>::IsEmpty(){
99. return currentSize == 0;
100.}
101.
102.template<class T>
103.bool MaxHeap<T>::IsFull(){
104. return currentSize == maxSize;
105.}
106.
107.template<class T>
108.void MaxHeap<T>::MakeEmpty(){
109. currentSize = 0
110.}
111.
112.MainApp.cpp测试文件:
113.
114.#include<iostream>
115.#include"MaxHeap.h"
116.using namespace std;
117.
118.void main(){
119. int a[5] = {3,2,1,4,5};
120. MaxHeap<int> m_heap(a,5);
121. int x,i;
122. for(i = 0; i < 5; i++){
123. m_heap.RemoveMax(x);
124. cout << x << " ";
125. }
126. cout << endl;
127.
128. for(i = 0; i < 5; i++){
129. m_heap.Insert(a[i]);
130. }
131.
132. for(i = 0; i < 5; i++){
133. m_heap.RemoveMax(x);
134. cout << x << " ";
135. }
136. cout << endl;
137.}
- heap stl
- STL【Heap】
- stl-heap
- heap STL
- STL Heap
- STL heap
- 使用stl实现heap
- STL heap用法
- STL Heap操作
- STL中的heap操作
- stl中的heap使用
- STL heap简单应用
- STL heap堆
- STL 之 heap
- stl heap sort
- STL heap 转载
- STL算法 ---------- Heap算法
- STL源码:heap
- Android -- Sensor 简介
- eclipse安装反编译插件(附jad下载)
- 各种数据库
- 自动提取摘要,自动提取第一张图片 思路
- ORACLE+10G+win7下载地址及安装方法
- STL Heap
- 爬虫遇到的问题
- CF 165(div2)
- sqlplus命令的使用大全
- Eclipse内置SVN插件的使用说明
- STL_queue_priority_queue
- 递归算法向非递归算法转换
- 浏览器是如何工作的系列:基本介绍
- Android金蛇剑之Gallery之沙场秋点兵