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 }