forked from aaronbloomfield/pdr
-
Notifications
You must be signed in to change notification settings - Fork 228
/
binary_heap.cpp.html
134 lines (120 loc) · 16.9 KB
/
binary_heap.cpp.html
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
128
129
130
131
132
133
134
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite">
<title>binary_heap.cpp</title>
</head>
<body style="background-color:white">
<pre><i><span style="color:#9A1900">// Code written by Aaron Bloomfield, 2014</span></i>
<i><span style="color:#9A1900">// Released under a CC BY-SA license</span></i>
<i><span style="color:#9A1900">// This code is part of the https://github.com/aaronbloomfield/pdr repository</span></i>
<b><span style="color:#000080">#include</span></b> <span style="color:#FF0000"><iostream></span>
<b><span style="color:#000080">#include</span></b> <span style="color:#FF0000">"binary_heap.h"</span>
<b><span style="color:#0000FF">using</span></b> <b><span style="color:#0000FF">namespace</span></b> std<span style="color:#990000">;</span>
<i><span style="color:#9A1900">// default constructor</span></i>
binary_heap<span style="color:#990000">::</span><b><span style="color:#000000">binary_heap</span></b><span style="color:#990000">()</span> <span style="color:#990000">:</span> <b><span style="color:#000000">heap_size</span></b><span style="color:#990000">(</span><span style="color:#993399">0</span><span style="color:#990000">)</span> <span style="color:#FF0000">{</span>
heap<span style="color:#990000">.</span><b><span style="color:#000000">push_back</span></b><span style="color:#990000">(</span><span style="color:#993399">0</span><span style="color:#990000">);</span>
<span style="color:#FF0000">}</span>
<i><span style="color:#9A1900">// builds a heap from an unsorted vector</span></i>
binary_heap<span style="color:#990000">::</span><b><span style="color:#000000">binary_heap</span></b><span style="color:#990000">(</span><span style="color:#008080">vector<int></span> vec<span style="color:#990000">)</span> <span style="color:#990000">:</span> <b><span style="color:#000000">heap_size</span></b><span style="color:#990000">(</span>vec<span style="color:#990000">.</span><b><span style="color:#000000">size</span></b><span style="color:#990000">())</span> <span style="color:#FF0000">{</span>
heap <span style="color:#990000">=</span> vec<span style="color:#990000">;</span>
heap<span style="color:#990000">.</span><b><span style="color:#000000">push_back</span></b><span style="color:#990000">(</span>heap<span style="color:#990000">[</span><span style="color:#993399">0</span><span style="color:#990000">]);</span>
heap<span style="color:#990000">[</span><span style="color:#993399">0</span><span style="color:#990000">]</span> <span style="color:#990000">=</span> <span style="color:#993399">0</span><span style="color:#990000">;</span>
<b><span style="color:#0000FF">for</span></b> <span style="color:#990000">(</span><span style="color:#009900">int</span> i <span style="color:#990000">=</span> heap_size<span style="color:#990000">/</span><span style="color:#993399">2</span><span style="color:#990000">;</span> i <span style="color:#990000">></span> <span style="color:#993399">0</span><span style="color:#990000">;</span> i<span style="color:#990000">--)</span> <span style="color:#FF0000">{</span>
<b><span style="color:#000000">percolateDown</span></b><span style="color:#990000">(</span>i<span style="color:#990000">);</span>
<span style="color:#FF0000">}</span>
<span style="color:#FF0000">}</span>
<i><span style="color:#9A1900">// the destructor doesn't need to do much</span></i>
binary_heap<span style="color:#990000">::~</span><b><span style="color:#000000">binary_heap</span></b><span style="color:#990000">()</span> <span style="color:#FF0000">{</span>
<span style="color:#FF0000">}</span>
<span style="color:#009900">void</span> binary_heap<span style="color:#990000">::</span><b><span style="color:#000000">insert</span></b><span style="color:#990000">(</span><span style="color:#009900">int</span> x<span style="color:#990000">)</span> <span style="color:#FF0000">{</span>
<i><span style="color:#9A1900">// a vector push_back will resize as necessary</span></i>
heap<span style="color:#990000">.</span><b><span style="color:#000000">push_back</span></b><span style="color:#990000">(</span>x<span style="color:#990000">);</span>
<i><span style="color:#9A1900">// move it up into the right position</span></i>
<b><span style="color:#000000">percolateUp</span></b><span style="color:#990000">(++</span>heap_size<span style="color:#990000">);</span>
<span style="color:#FF0000">}</span>
<span style="color:#009900">void</span> binary_heap<span style="color:#990000">::</span><b><span style="color:#000000">percolateUp</span></b><span style="color:#990000">(</span><span style="color:#009900">int</span> hole<span style="color:#990000">)</span> <span style="color:#FF0000">{</span>
<i><span style="color:#9A1900">// get the value just inserted</span></i>
<span style="color:#009900">int</span> x <span style="color:#990000">=</span> heap<span style="color:#990000">[</span>hole<span style="color:#990000">];</span>
<i><span style="color:#9A1900">// while we haven't run off the top and while the</span></i>
<i><span style="color:#9A1900">// value is less than the parent...</span></i>
<b><span style="color:#0000FF">for</span></b> <span style="color:#990000">(</span> <span style="color:#990000">;</span> <span style="color:#990000">(</span>hole <span style="color:#990000">></span> <span style="color:#993399">1</span><span style="color:#990000">)</span> <span style="color:#990000">&&</span> <span style="color:#990000">(</span>x <span style="color:#990000"><</span> heap<span style="color:#990000">[</span>hole<span style="color:#990000">/</span><span style="color:#993399">2</span><span style="color:#990000">]);</span> hole <span style="color:#990000">/=</span> <span style="color:#993399">2</span><span style="color:#990000">)</span> <span style="color:#FF0000">{</span>
heap<span style="color:#990000">[</span>hole<span style="color:#990000">]</span> <span style="color:#990000">=</span> heap<span style="color:#990000">[</span>hole<span style="color:#990000">/</span><span style="color:#993399">2</span><span style="color:#990000">];</span> <i><span style="color:#9A1900">// move the parent down</span></i>
<span style="color:#FF0000">}</span>
<i><span style="color:#9A1900">// correct position found! insert at that spot</span></i>
heap<span style="color:#990000">[</span>hole<span style="color:#990000">]</span> <span style="color:#990000">=</span> x<span style="color:#990000">;</span>
<span style="color:#FF0000">}</span>
<span style="color:#009900">int</span> binary_heap<span style="color:#990000">::</span><b><span style="color:#000000">deleteMin</span></b><span style="color:#990000">()</span> <span style="color:#FF0000">{</span>
<i><span style="color:#9A1900">// make sure the heap is not empty</span></i>
<b><span style="color:#0000FF">if</span></b> <span style="color:#990000">(</span>heap_size <span style="color:#990000">==</span> <span style="color:#993399">0</span><span style="color:#990000">)</span> <span style="color:#FF0000">{</span>
<b><span style="color:#0000FF">throw</span></b> <span style="color:#FF0000">"deleteMin() called on empty heap"</span><span style="color:#990000">;</span>
<span style="color:#FF0000">}</span>
<i><span style="color:#9A1900">// save the value to be returned</span></i>
<span style="color:#009900">int</span> ret <span style="color:#990000">=</span> heap<span style="color:#990000">[</span><span style="color:#993399">1</span><span style="color:#990000">];</span>
<i><span style="color:#9A1900">// move the last inserted position into the root</span></i>
heap<span style="color:#990000">[</span><span style="color:#993399">1</span><span style="color:#990000">]</span> <span style="color:#990000">=</span> heap<span style="color:#990000">[</span>heap_size<span style="color:#990000">--];</span>
<i><span style="color:#9A1900">// make sure the vector knows that there is one less element</span></i>
heap<span style="color:#990000">.</span><b><span style="color:#000000">pop_back</span></b><span style="color:#990000">();</span>
<i><span style="color:#9A1900">// percolate the root down to the proper position</span></i>
<b><span style="color:#0000FF">if</span></b> <span style="color:#990000">(!</span><b><span style="color:#000000">isEmpty</span></b><span style="color:#990000">())</span> <span style="color:#FF0000">{</span>
<b><span style="color:#000000">percolateDown</span></b><span style="color:#990000">(</span><span style="color:#993399">1</span><span style="color:#990000">);</span>
<span style="color:#FF0000">}</span>
<i><span style="color:#9A1900">// return the old root node</span></i>
<b><span style="color:#0000FF">return</span></b> ret<span style="color:#990000">;</span>
<span style="color:#FF0000">}</span>
<span style="color:#009900">void</span> binary_heap<span style="color:#990000">::</span><b><span style="color:#000000">percolateDown</span></b><span style="color:#990000">(</span><span style="color:#009900">int</span> hole<span style="color:#990000">)</span> <span style="color:#FF0000">{</span>
<i><span style="color:#9A1900">// get the value to percolate down</span></i>
<span style="color:#009900">int</span> x <span style="color:#990000">=</span> heap<span style="color:#990000">[</span>hole<span style="color:#990000">];</span>
<i><span style="color:#9A1900">// while there is a left child...</span></i>
<b><span style="color:#0000FF">while</span></b> <span style="color:#990000">(</span>hole<span style="color:#990000">*</span><span style="color:#993399">2</span> <span style="color:#990000"><=</span> heap_size<span style="color:#990000">)</span> <span style="color:#FF0000">{</span>
<span style="color:#009900">int</span> child <span style="color:#990000">=</span> hole<span style="color:#990000">*</span><span style="color:#993399">2</span><span style="color:#990000">;</span> <i><span style="color:#9A1900">// the left child</span></i>
<i><span style="color:#9A1900">// is there a right child? if so, is it lesser?</span></i>
<b><span style="color:#0000FF">if</span></b> <span style="color:#990000">((</span>child<span style="color:#990000">+</span><span style="color:#993399">1</span> <span style="color:#990000"><=</span> heap_size<span style="color:#990000">)</span> <span style="color:#990000">&&</span> <span style="color:#990000">(</span>heap<span style="color:#990000">[</span>child<span style="color:#990000">+</span><span style="color:#993399">1</span><span style="color:#990000">]</span> <span style="color:#990000"><</span> heap<span style="color:#990000">[</span>child<span style="color:#990000">]))</span> <span style="color:#FF0000">{</span>
child<span style="color:#990000">++;</span>
<span style="color:#FF0000">}</span>
<i><span style="color:#9A1900">// if the child is greater than the node...</span></i>
<b><span style="color:#0000FF">if</span></b> <span style="color:#990000">(</span>x <span style="color:#990000">></span> heap<span style="color:#990000">[</span>child<span style="color:#990000">])</span> <span style="color:#FF0000">{</span>
heap<span style="color:#990000">[</span>hole<span style="color:#990000">]</span> <span style="color:#990000">=</span> heap<span style="color:#990000">[</span>child<span style="color:#990000">];</span> <i><span style="color:#9A1900">// move child up</span></i>
hole <span style="color:#990000">=</span> child<span style="color:#990000">;</span> <i><span style="color:#9A1900">// move hole down</span></i>
<span style="color:#FF0000">}</span> <b><span style="color:#0000FF">else</span></b> <span style="color:#FF0000">{</span>
<b><span style="color:#0000FF">break</span></b><span style="color:#990000">;</span>
<span style="color:#FF0000">}</span>
<span style="color:#FF0000">}</span>
<i><span style="color:#9A1900">// correct position found! insert at that spot</span></i>
heap<span style="color:#990000">[</span>hole<span style="color:#990000">]</span> <span style="color:#990000">=</span> x<span style="color:#990000">;</span>
<span style="color:#FF0000">}</span>
<span style="color:#009900">int</span> binary_heap<span style="color:#990000">::</span><b><span style="color:#000000">findMin</span></b><span style="color:#990000">()</span> <span style="color:#FF0000">{</span>
<b><span style="color:#0000FF">if</span></b> <span style="color:#990000">(</span>heap_size <span style="color:#990000">==</span> <span style="color:#993399">0</span><span style="color:#990000">)</span> <span style="color:#FF0000">{</span>
<b><span style="color:#0000FF">throw</span></b> <span style="color:#FF0000">"findMin() called on empty heap"</span><span style="color:#990000">;</span>
<span style="color:#FF0000">}</span>
<b><span style="color:#0000FF">return</span></b> heap<span style="color:#990000">[</span><span style="color:#993399">1</span><span style="color:#990000">];</span>
<span style="color:#FF0000">}</span>
<span style="color:#009900">unsigned</span> <span style="color:#009900">int</span> binary_heap<span style="color:#990000">::</span><b><span style="color:#000000">size</span></b><span style="color:#990000">()</span> <span style="color:#FF0000">{</span>
<b><span style="color:#0000FF">return</span></b> heap_size<span style="color:#990000">;</span>
<span style="color:#FF0000">}</span>
<span style="color:#009900">void</span> binary_heap<span style="color:#990000">::</span><b><span style="color:#000000">makeEmpty</span></b><span style="color:#990000">()</span> <span style="color:#FF0000">{</span>
heap_size <span style="color:#990000">=</span> <span style="color:#993399">0</span><span style="color:#990000">;</span>
heap<span style="color:#990000">.</span><b><span style="color:#000000">resize</span></b><span style="color:#990000">(</span><span style="color:#993399">1</span><span style="color:#990000">);</span>
<span style="color:#FF0000">}</span>
<span style="color:#009900">bool</span> binary_heap<span style="color:#990000">::</span><b><span style="color:#000000">isEmpty</span></b><span style="color:#990000">()</span> <span style="color:#FF0000">{</span>
<b><span style="color:#0000FF">return</span></b> heap_size <span style="color:#990000">==</span> <span style="color:#993399">0</span><span style="color:#990000">;</span>
<span style="color:#FF0000">}</span>
<span style="color:#009900">void</span> binary_heap<span style="color:#990000">::</span><b><span style="color:#000000">print</span></b><span style="color:#990000">()</span> <span style="color:#FF0000">{</span>
cout <span style="color:#990000"><<</span> <span style="color:#FF0000">"("</span> <span style="color:#990000"><<</span> heap<span style="color:#990000">[</span><span style="color:#993399">0</span><span style="color:#990000">]</span> <span style="color:#990000"><<</span> <span style="color:#FF0000">") "</span><span style="color:#990000">;</span>
<b><span style="color:#0000FF">for</span></b> <span style="color:#990000">(</span><span style="color:#009900">int</span> i <span style="color:#990000">=</span> <span style="color:#993399">1</span><span style="color:#990000">;</span> i <span style="color:#990000"><=</span> heap_size<span style="color:#990000">;</span> i<span style="color:#990000">++)</span> <span style="color:#FF0000">{</span>
cout <span style="color:#990000"><<</span> heap<span style="color:#990000">[</span>i<span style="color:#990000">]</span> <span style="color:#990000"><<</span> <span style="color:#FF0000">" "</span><span style="color:#990000">;</span>
<i><span style="color:#9A1900">// next line from http://tinyurl.com/mf9tbgm</span></i>
<span style="color:#009900">bool</span> isPow2 <span style="color:#990000">=</span> <span style="color:#990000">(((</span>i<span style="color:#990000">+</span><span style="color:#993399">1</span><span style="color:#990000">)</span> <span style="color:#990000">&</span> <span style="color:#990000">~(</span>i<span style="color:#990000">))==(</span>i<span style="color:#990000">+</span><span style="color:#993399">1</span><span style="color:#990000">))?</span> i<span style="color:#990000">+</span><span style="color:#993399">1</span> <span style="color:#990000">:</span> <span style="color:#993399">0</span><span style="color:#990000">;</span>
<b><span style="color:#0000FF">if</span></b> <span style="color:#990000">(</span>isPow2<span style="color:#990000">)</span> <span style="color:#FF0000">{</span>
cout <span style="color:#990000"><<</span> endl <span style="color:#990000"><<</span> <span style="color:#FF0000">"</span><span style="color:#CC33CC">\t</span><span style="color:#FF0000">"</span><span style="color:#990000">;</span>
<span style="color:#FF0000">}</span>
<span style="color:#FF0000">}</span>
cout <span style="color:#990000"><<</span> endl<span style="color:#990000">;</span>
<span style="color:#FF0000">}</span>
</pre>
</body>
</html>