自己写的小根堆类
发现一个问题:堆并没有不允许出现重复元素这个性质,之前一直有错误的印象
当类中含有vector数据成员时,构造函数怎么写?答案是不写,交给vector的默认构造函数处理.
#include <iostream>
#include <vector>
using namespace std;
template<typename T>
class MinHeap{
//int* heap; //使用指针变量来指向一片存储区域,是否是一个不好的习惯?
vector<T> heap;
void siftDown(int root, int bound, vector<T>& a) {
int l_idx;
int r_idx;
int next;
T temp;
while (2*root+1 <= bound) {
l_idx = 2 * root + 1;
r_idx = 2 * root + 2;
if (r_idx <= bound) next = a[l_idx]<a[r_idx]? l_idx: r_idx;
else next = l_idx;
if (a[root] > a[next]) {
temp = a[root];
a[root] = a[next];
a[next] = temp;
root = next;
}
else return;
}
}
void siftUp(int start) { //start是末尾点
if ((start-1)/2 < 0) return;
else {
int root = (start-1)/2;
T temp;
while (start > 0) {
if (heap[root] > heap[start]) {
temp = heap[root];
heap[root] = heap[start];
heap[start] = temp;
start = root; //更新start
root = (start - 1) / 2; //更新root
//cout << "root=" << root << endl;
//cout << "start=" << start << endl;
}
else return;
}
}
}
public:
MinHeap(int left, int right, T a[]){
for (int i = left; i <= right; ++i)
heap.push_back(a[i]);
createMinHeap();
}
void show() {
for (int i = 0; i < size(); ++i)
cout << heap[i] << " ";
cout << endl;
}
void createMinHeap() {
cout << "orin:";
show();
for (int i = (heap.size()-2)/2; i >= 0; --i) {
cout << "i=" << i << ", ";
siftDown(i, heap.size()-1, heap);
cout << "after one siftDown:" ;
show();
}
cout << "minHeap:";
show();
}
void Insert(T val) {
heap.push_back(val);
siftUp(size()-1);
show();
}
bool Remove(T& elem) {
if (heap.size() <= 0) return false;
elem = heap[0];
heap[0] = heap[heap.size()-1];
heap.pop_back();
siftDown(0, heap.size()-1, heap);
//cout << "after remove:";
//show();
//cout << "elem=" << elem << endl;
return true;
}
int size() {
return heap.size();
}
};
int main() {
int a[10] = {0, 9, 8, 7, 6, 5, 4, 3, 2, 1};
MinHeap<int> h(0, 9, a);
//h.createMinHeap();
h.Insert(-1);
h.Insert(7); //重复数,
h.Insert(12);
int b[12];
for (int i = 0; i < 12; ++i)
h.Remove(b[i]);
cout << "b:";
for (int i = 0; i < 12; ++i)
cout << b[i] << " ";
cout << endl;
system("pause");
return 0;
}