-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbinheap.c
128 lines (102 loc) · 2.78 KB
/
binheap.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* Based on Data Structures and Algorithm Analysis in C (Second Edition)
* by Mark Allen Weiss.
*
* Modified by Christian Bienia, Minlan Yu.
*/
#include <stdlib.h>
#include <stdio.h>
#include "binheap.h"
/* Macros for error handling */
#define Error( Str ) FatalError( Str )
#define FatalError( Str ) fprintf( stderr, "Binary Heap: %s\n", Str ), exit( 1 )
#define MinPQSize (16)
PriorityQueue Initialize( int InitCapacity ) {
PriorityQueue H;
if( InitCapacity < MinPQSize ) {
Error( "Priority queue size is too small" );
}
H = malloc( sizeof( struct HeapStruct ) );
if( H ==NULL ) {
FatalError( "Out of space!!!" );
}
/* Allocate the array plus one extra for sentinel */
H->Elements = malloc( ( InitCapacity + 1 ) * sizeof( HeapElementType ) );
if( H->Elements == NULL ) {
FatalError( "Out of space!!!" );
}
H->Capacity = InitCapacity;
H->Size = 0;
H->Elements[0] = NULL;
return H;
}
void MakeEmpty( PriorityQueue H ) {
H->Size = 0;
}
void Insert( HeapElementType X, PriorityQueue H ) {
int i;
if( IsFull( H ) ) {
/* double capacity of heap */
H->Capacity = 2 * H->Capacity;
H->Elements = realloc( H->Elements, ( H->Capacity + 1 ) * sizeof( HeapElementType ) );
if( H->Elements == NULL ) {
FatalError( "Out of space!!!" );
}
}
/* NOTE: H->Element[ 0 ] is a sentinel */
if (H->Size == 0) {
H->Elements[1] = X;
H->Size = 1;
return;
}
H->Size++;
for( i = H->Size; H->Elements[i/2]!= NULL && H->Elements[ i / 2 ]->sequence.l2num > X->sequence.l2num; i /= 2 ) {
H->Elements[ i ] = H->Elements[ i / 2 ];
}
H->Elements[ i ] = X;
}
HeapElementType DeleteMin( PriorityQueue H ) {
HeapElementType MinElement, LastElement;
int i, Child;
if( IsEmpty( H ) ) {
Error( "Priority queue is empty" );
return H->Elements[ 0 ];
}
MinElement = H->Elements[ 1 ];
LastElement = H->Elements[ H->Size-- ];
for( i = 1; i * 2 <= H->Size; i = Child ) {
/* Find smaller child */
Child = i * 2;
if( Child != H->Size && H->Elements[ Child + 1 ]->sequence.l2num < H->Elements[ Child ]->sequence.l2num ) {
Child++;
}
/* Percolate one level */
if( LastElement->sequence.l2num > H->Elements[ Child ]->sequence.l2num ) {
H->Elements[ i ] = H->Elements[ Child ];
} else {
break;
}
}
H->Elements[ i ] = LastElement;
return MinElement;
}
HeapElementType FindMin( PriorityQueue H ) {
if( !IsEmpty( H ) ) {
return H->Elements[ 1 ];
} else {
//FatalError( "Priority Queue is Empty" );
return NULL;
}
}
int IsEmpty( PriorityQueue H ) {
return (H->Size == 0);
}
int IsFull( PriorityQueue H ) {
return H->Size == H->Capacity;
}
int NumberElements( PriorityQueue H ) {
return H->Size;
}
void Destroy( PriorityQueue H ) {
free( H->Elements );
free( H );
}