-
Notifications
You must be signed in to change notification settings - Fork 0
/
Heap.hpp
151 lines (129 loc) · 3.46 KB
/
Heap.hpp
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <iostream> // cout
#include "Heap.h"
// constructor implementation
template <class T>
Heap<T>::Heap(){
std::cout<< "Heap data structure created" << std::endl;
}
template <class T>
Heap<T>::Heap(std::vector<T>& items){
// Initialize the vector conatainer
container_ = items;
std::cout<< "address of container_ = " << &container_ << std::endl;
std::cout<< "address of items = " << &items << std::endl;
}
/** 3 steps for template function
1- add template <class T>
2- put <T> after class name to indicate the T version of the class
3- put T to replace intended variable type everywhere
*/
template <class T>
T Heap<T>::extractMin(){
return container_[0];
}
template <class T>
void Heap<T>::removeMin(){
swap(0, _getLastIdx());
_heapifyDn(0);
}
template<class T>
void Heap<T>::buildHeap(){
int idx = _getLastIdx();
while (idx >= 0){
_heapifyDn(idx);
idx--;
}
}
template<class T>
void Heap<T>::_heapifyDn(int i){
std::cout << "[heapifyDn] node " << i << std::endl;
int idxL, idxR, idxMinChild;
while(!_isLeaf(i)){
idxL = _getLeftChildIdx(i);
idxR = _getRightChildIdx(i);
// since this is not leaf, there is at least a left child
// if no right child
if (idxR == -1) {
idxMinChild = idxL;
}
else if (container_[idxL]< container_[idxR]) { idxMinChild = idxL;}
else { idxMinChild = idxR;}
if (container_[i] > container_[idxMinChild]) {
_swap(idxMinChild, i);
i = idxMinChild;
}else{
return; //break ??
}
}
}
template <typename T>
bool Heap<T>::_isLeaf(const int i){
if (_getLeftChildIdx(i) == -1 && _getRightChildIdx(i) == -1){
return 1;
} else {
return 0;
}
}
template <typename T> // or template <class T> ???????
int Heap<T>::_getLeftChildIdx(const int idx){
//(idx+1)*2-1 = idx*2 +1
int childIdx = idx*2+1;
if (childIdx <= _getLastIdx()){
return childIdx;
}
else {
return -1;
}
}
template <typename T>
int Heap<T>::_getRightChildIdx(const int idx){
int childIdx = idx*2 + 2;
if (childIdx <= _getLastIdx()){
return childIdx;
}
else {
return -1;
}
}
template<class T>
void Heap<T>::insert(T item){
// add item to end of vector
container_.push_back(item);
std::cout << "Item added" << std::endl;
// heapify up
int idx = _getLastIdx();
_heapifyUp(idx);
}
template <typename T>
void Heap<T>::_heapifyUp(int idx){
int idxParent = _getParentIdx(idx);
while (idx > 0 && container_[idx] < container_[idxParent]){
_swap (idx, idxParent);
idx = idxParent;
idxParent = _getParentIdx(idx);
}
}
template <typename T>
void Heap<T>::_swap(int idx, int idxParent){
T temp = container_[idx];
container_[idx] = container_[idxParent];
container_[idxParent] = temp;
// map [container_[idx]] = idx
}
template <typename T>
int Heap<T>::_getLastIdx(){
return container_.size()-1;
}
template <typename T>
std::ostream& Heap<T>::print(std::ostream& os){
for(T item: container_){
os << item << " " ;
}
return os;
}
/*
template <typename T>
std::ostream& operator<<(std::ostream& os, const Heap<T>& myHeap){
myHeap.print(os);
return os;
}*/