二叉堆 算法基础篇(一)
View Code
1 // suanfa.cpp : 定义控制台应用程序的入口点。 2 // 3 /********************************************************* 4 ********************优先级队列之堆 *********************** 5 6 7 设计者:cslave 8 代码免责说明: 9 本代码可以拷贝使用,或者用于商业应用,但是由代码本身问题 10 所导致的损失,本人概不负责。 11 **********************************************************/ 12 13 #include "stdafx.h" 14 #include <stdio.h> 15 #include <string> 16 #include <assert.h> 17 #include <iostream> 18 using namespace std; 19 #define MinData 0x80000000 20 #define MinPQSize 1 21 typedef int ElementType; 22 23 struct HeapStruct //堆结构 堆需要三个变量,1 数组 存储元素 2 容量,最大存储元素个数 3 大小 堆的体格大小 24 { 25 int capacity; 26 int size; 27 ElementType *Elements; 28 }; 29 30 typedef struct HeapStruct* PriorityQueue; 31 32 33 PriorityQueue Initialize(PriorityQueue H,int MaxElements) //堆的初始化 34 { 35 try 36 { 37 if(H==NULL) 38 throw "error memory"; 39 if(MaxElements<MinPQSize) 40 throw "capacity too little"; 41 } 42 catch (char* sz) 43 { 44 cout<<sz<<endl; 45 } 46 H->Elements=(ElementType* )malloc((MaxElements+1)*sizeof(ElementType)); //堆数据是从1开始的 所以要多申请一个变量 47 H->capacity=MaxElements; 48 H->size=0; 49 H->Elements[0]=MinData; 50 return H; 51 52 } 53 54 bool IsFul(PriorityQueue H) //判断堆是否为满 55 { 56 if(H->capacity<=H->size) 57 { 58 return true; 59 } 60 return false; 61 } 62 63 void Insert(ElementType X,PriorityQueue H) //堆的插入算法 复杂度为log(n) 64 { 65 int i; 66 try 67 { 68 if(IsFul(H)) 69 { 70 cerr<<"PriorityQueue is Ful"; 71 return; 72 } 73 } 74 catch (char* sz) 75 { 76 cout<<sz<<endl; 77 } 78 for(i=++H->size;H->Elements[i/2]>X;i/=2) //和父节点比较相互调换 直至根节点。 79 H->Elements[i]=H->Elements[i/2]; 80 H->Elements[i]=X; 81 } 82 bool IsEmpty(PriorityQueue H) //判断堆是否为空 83 { 84 return(H->size==0); 85 } 86 87 ElementType DeleteMin(PriorityQueue H) //删除小顶堆的堆顶元素,此算法可用于排序。复杂度log(n) 88 { 89 90 int i ,child; 91 ElementType MinElement,LastElement; 92 try 93 { 94 if(IsEmpty(H)) 95 { 96 throw "PriorityQueue is empty!"; 97 return H->Elements[0]; 98 } 99 } 100 catch (char* sz) 101 { 102 cout<<sz<<endl; 103 } 104 MinElement=H->Elements[1]; 105 LastElement=H->Elements[H->size--]; 106 for(i=1;i*2<=H->size;i=child) //堆的调整,让最小元素上升作为父亲 107 { 108 child=2*i; 109 if(child!=H->size&&H->Elements[child+1]<H->Elements[child]) 110 child++; 111 if(LastElement>H->Elements[child]) 112 H->Elements[i]=H->Elements[child]; 113 else 114 break; 115 } 116 H->Elements[i]=LastElement; 117 return MinElement; 118 } 119 120 void IncreaseKey(PriorityQueue H,int index,ElementType key) 121 { 122 assert(index>=1); 123 int child; 124 int i; 125 H->Elements[index]=key; 126 for(i=index;2*i<=H->size;i=child) //对堆进行调整,找到小儿子,调换。 127 { 128 child=2*i; 129 if(child!=H->size&&H->Elements[child]>H->Elements[child+1]) 130 child++; 131 if(key<H->Elements[child]) 132 break; 133 H->Elements[i]=H->Elements[child]; 134 } 135 H->Elements[i]=key; 136 } 137 void DecreaseKey(PriorityQueue H,int index,ElementType key) 138 { 139 assert(index>=1); 140 int parent; 141 int i; 142 H->Elements[index]=key; 143 for(i=index;i/2>=1;i=parent) //和父亲作对比,然后对调 144 { 145 parent=i/2; 146 if(key>H->Elements[parent]) 147 break; 148 H->Elements[i]=H->Elements[parent]; 149 } 150 H->Elements[i]=key; 151 } 152 153 void PrintQueueNode(PriorityQueue H) 154 { 155 for(int i=1;i<H->size+1;i++) 156 cout<<i<<":"<<H->Elements[i]<<"\t"; 157 cout<<endl; 158 } 159 160 void PercolateDown(PriorityQueue H,int index) //下虑函数 161 { 162 if(H==NULL) return; 163 int i,child; 164 ElementType temp; 165 for(i=index;2*i<=H->size;i=child) 166 { 167 child=2*i; 168 if(child!=H->size&&H->Elements[child+1]<H->Elements[child]) 169 child++; 170 if(H->Elements[i]<H->Elements[child]) 171 break; 172 temp=H->Elements[child]; 173 H->Elements[child]=H->Elements[i]; 174 H->Elements[i]=temp; 175 176 } 177 } 178 179 180 181 void PercolateUp(PriorityQueue H,int index) //上虑函数 182 { 183 if(H==NULL) return; 184 int i,parent; 185 ElementType temp; 186 for(i=index;2/i>=1;i=parent) 187 { 188 parent=i/2; 189 if(H->Elements[i]>H->Elements[parent]) 190 break; 191 temp=H->Elements[parent]; 192 H->Elements[parent]=H->Elements[i]; 193 H->Elements[i]=temp; 194 195 } 196 } 197 198 void BuildHeap(PriorityQueue H) //建堆,逐次过滤,从(H->size)/2开始,就是从倒数第二层开始往上,逐层向下过滤,这个值可以舍弃没有子节点的数据 199 { 200 assert(H!=NULL); 201 int i; 202 for( i=(H->size)/2;i>=1;i--) 203 PercolateDown(H,i); 204 } 205 206 int _tmain(int argc, _TCHAR* argv[]) 207 { 208 int MaxElements; 209 int index,key; 210 // ElementType arr[10]={13,21,16,24,31,19,68,65,26,32}; 211 ElementType arr[10]={13,14,19,65,26,21,32,31,16,19}; 212 cout<<"Please Input the MaxElement!"<<endl; 213 cin>>MaxElements; 214 215 PriorityQueue H=(PriorityQueue )malloc(MaxElements*sizeof(struct HeapStruct)); 216 217 Initialize( H, MaxElements); 218 #if 0 219 for(int i=0;i<10;i++) 220 { 221 Insert(arr[i],H); 222 } 223 PrintQueueNode(H); 224 225 cout<<"Please input the index and key you want to "<<endl; 226 cin>>index>>key; 227 228 //IncreaseKey( H, index, key); 229 DecreaseKey(H,index,key); 230 PrintQueueNode(H); 231 #endif 232 233 cout<<"BuidHeap have begun"<<endl; 234 for(int i=0;i<10;i++) 235 { 236 H->Elements[i+1]=arr[i]; 237 H->size++; 238 } 239 PrintQueueNode(H); 240 BuildHeap(H); 241 PrintQueueNode(H); 242 243 for(int j=0;j<10;j++) 244 cout<<DeleteMin(H)<<" "; 245 return 0; 246 }