大顶堆是一种特殊的完全二叉树,其中每个父节点的值都大于其子节点的值。这种数据结构在优先队列、堆排序等算法中有着广泛的应用。本文将通过C++代码示例来展示大顶堆的实现(小顶堆看结尾):
1:用动态数组存储树节点元素
vector<int> maxHeap;
2:获取左子节点,右子节点,父节点
//获取左子节点
int leftSon(int i) {
return 2 * i + 1;//根节点算0
}
//获取右子节点
int rightSon(int i) {
return 2 * i + 2; // 根节点算0
}
//获取父节点
int parent(int i) {
return (i - 1) / 2;
}
3:访问堆顶元素功能
//访问堆顶元素
int top() {
return maxHeap[0];
}
4:向上堆化和向下堆化功能(插入元素后使用向上堆化,删除元素使用向下堆化)
//向上堆化
void siftUp(int i) {
while (true) {
int p = parent(i);
if (p < 0 || maxHeap[i] <= maxHeap[p]) {
break;
}
else {
swap(maxHeap[i], maxHeap[p]);
i = p;
}
}
}
//向下堆化
void siftDown(int i) {
while (true) {
int m = i;
if (leftSon(i) < maxHeap.size() && maxHeap[leftSon(i)] > maxHeap[m]) {
m = leftSon(i);
}
if (rightSon(i) < maxHeap.size() && maxHeap[rightSon(i)] > maxHeap[m]) {
m = rightSon(i);
}
if (m == i) {
break;
}
swap(maxHeap[i], maxHeap[m]);
i = m;
}
}
5:插入元素
//插入元素
void push(int val) {
maxHeap.push_back(val);
siftUp(maxHeap.size() - 1);
}
6:删除堆顶元素
//堆顶元素出堆
void pop() {
if (maxHeap.size() == 0) {
throw out_of_range("堆为空");
}
swap(maxHeap[0], maxHeap[maxHeap.size() - 1]);
maxHeap.pop_back();
siftDown(0);
}
7:访问堆顶元素
//访问堆顶元素
int top() {
return maxHeap[0];
}
8:完整代码
#include <iostream>
#include <queue>
using namespace std;
/*
堆:完全二叉树的特例,分为大顶堆和小顶堆
*/
class Heap {
public:
vector<int> maxHeap;
//获取左子节点
int leftSon(int i) {
return 2 * i + 1;//根节点算0
}
//获取右子节点
int rightSon(int i) {
return 2 * i + 2; // 根节点算0
}
//获取父节点
int parent(int i) {
return (i - 1) / 2;
}
//访问堆顶元素
int top() {
return maxHeap[0];
}
//插入元素
void push(int val) {
maxHeap.push_back(val);
siftUp(maxHeap.size() - 1);
}
//向上堆化
void siftUp(int i) {
while (true) {
int p = parent(i);
if (p < 0 || maxHeap[i] <= maxHeap[p]) {
break;
}
else {
swap(maxHeap[i], maxHeap[p]);
i = p;
}
}
}
//向下堆化
void siftDown(int i) {
while (true) {
int m = i;
if (leftSon(i) < maxHeap.size() && maxHeap[leftSon(i)] > maxHeap[m]) {
m = leftSon(i);
}
if (rightSon(i) < maxHeap.size() && maxHeap[rightSon(i)] > maxHeap[m]) {
m = rightSon(i);
}
if (m == i) {
break;
}
swap(maxHeap[i], maxHeap[m]);
i = m;
}
}
//堆顶元素出堆
void pop() {
if (maxHeap.size() == 0) {
throw out_of_range("堆为空");
}
swap(maxHeap[0], maxHeap[maxHeap.size() - 1]);
maxHeap.pop_back();
siftDown(0);
}
};
int main() {
Heap maxHeap;
maxHeap.push(1);
maxHeap.push(4);
maxHeap.push(3);
maxHeap.push(9);
maxHeap.push(5);
maxHeap.push(8);
cout << "堆顶元素:";
cout << maxHeap.top() << endl;
cout << "删除堆顶元素:" << endl;
maxHeap.pop();
cout << "堆顶元素:";
cout << maxHeap.top() << endl;
system("pause");
return 0;
}
运行结果:
9:tips
只需将向上堆化和向下堆化中的>换成<即可!