二叉堆 算法基础篇(一)

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 }
原文地址:https://www.cnblogs.com/cslave/p/2544990.html