c++中有priority_queue容器,可以用来表示最小堆。本文将根据堆的原理自行实现最小堆。
实现代码如下:
#include<iostream>
#include<vector>
/*辅助函数:交换两位置的元素*/
void swap(std::vector<int> &heap,int i,int j){
int tmp = heap[i];
heap[i] = heap[j];
heap[j] = tmp;
}
/*辅助函数:将元素上移,保持最小堆性质 */
void heapifyUp(std::vector<int> &heap,int index){
while(index > 0){
int parent = (index - 1) / 2;
// 改函数只会在建堆时调用,当插入元素时是在尾部插入,
// 但此时之前的元素已经具有最小堆的性质,故只要调整改插入元素
if(heap[index] < heap[parent]){
swap(heap,index,parent);
index = parent;
}else{
break;
}
}
}
/*辅助函数:将元素下移,保持最小堆性质 */
void heapifyDown(std::vector<int> &heap,int index){
int size = heap.size();
while(true){
int left = index * 2 + 1;
int right = index * 2 + 2;
int smallest = index;
if(left < size && heap[left]<heap[smallest]){
smallest = left;
}
if(right < size && heap[right]<heap[smallest]){
smallest = right;
}
if(smallest!=index){
swap(heap,index,smallest);
index = smallest;
}else {
break;
}
}
}
// 删除堆顶元素(最小值)
void removeMin(std::vector<int> &heap){
if(heap.empty()) return ;
int last = heap.back();
heap.pop_back();
heap.front() = last;
heapifyDown(heap,0);
}
// 插入元素到最小堆
void insert(std::vector<int> &heap,int value){
heap.push_back(value);
heapifyUp(heap,heap.size()-1);
}
// 输出最小堆中的所有元素
void printHeap(std::vector<int> &heap){
for(int value:heap){
std::cout << value << " ";
}
std::cout << std::endl;
}
int main(){
std::vector<int> minHeap;
insert(minHeap, 5);
insert(minHeap, 2);
insert(minHeap, 10);
insert(minHeap, 3);
insert(minHeap, 7);
printHeap(minHeap);
removeMin(minHeap);
printHeap(minHeap);
return 0;
}
在命令行输入
g++ -std=c++11 main.cpp -o heap.exe
生成heap.exe可执行文件。
最后的执行结果如下:
2 3 10 5 7
3 5 10 7