堆是一棵有着特殊性质的完全二叉树,可以用优先级队列(priority queue)实现
堆的性质:
1.是一棵完全二叉树
2.树的每个结点,如果存在子树,那么该结点的权值大于等于(或小于等于)子树中所有的结点的权值
如果根节点大于等于子树结点的权值,称为大根堆;反之,称为小根堆
由于堆是一个完全二叉树,因此可以用一个数组来存储
const int N = 1e5 + 10;
int n; // 标记堆的大小
int heap[N]; // 存堆(默认大根堆)
void up(int child) // 向上调整算法(孩子向上走,比父亲大就交换)
{
int parent = child / 2;
while(parent >= 1 && heap[child] > heap[parent])
{
swap(heap[child], heap[parent]);
// 先变形参
child = parent;
parent = child / 2;
}
}
void down(int parent) // 向下调整算法(父亲向下走,与大孩子小就交换)
{
int child = parent * 2;
while(child <= n)
{
if(child + 1 <= n && heap[child + 1] > heap[child]) child++;
if(heap[child] <= heap[parent]) return;
swap(heap[child], heap[parent]);
parent = child;
child = parent * 2;
}
}
const int N = 1e6 + 10;
int n; // 标记堆的大小
int heap[N]; // 存堆(大根堆)
// 插入(把新来的元素放在最后一个位置,执行一次向上调整算法)
void push(int x)
{
heap[++n] = x;
up(n);
}
void pop()
{
swap(heap[1], heap[n]);
n--;
down(1);
}
下标为1位置的元素就是堆顶元素
int top()
{
return heap[1];
}
int size()
{
return n;
}
#include
#include
#include // 优先级队列在头文件queue中
using namespace std;
void test1()
{
int a[10] = {1, 41, 23, 10, 11, 2, -1, 99, 14, 0};
priority_queue heap; // 默认是大根堆
for(auto x : a)
{
heap.push(x); // 插入元素
}
while(heap.size())
{
cout << heap.top() << " "; // 获取堆顶元素
heap.pop(); // 删除元素
}
}
int main()
{
test();
return 0;
}
#include
#include
#include
using namespace std;
struct node
{
int a, b, c;
// //以 b 为基准,定义大根堆
// bool operator < (const node& x) const
// {
// return b < x.b;
// }
// 以 b 为基础,定义小根堆
bool operator < (const node& x) const
{
return b > x.b;
}
};
void test()
{
priority_queue heap;
for(int i = 1; i <= 10; i++)
{
heap.push({i, i + 1, i * 2});
}
while(heap.size())
{
auto [a, b, c] = heap.top();
heap.pop();
cout << a << " " << b << " " c << endl;
}
}
int main()
{
test();
return 0;
}
#include
#include
#include
using namespace std;
void test()
{
int a[10] = {1, 41, 23, 10, 11, 2, -1, 99, 14, 0};
priority_queue heap1; // 默认大根堆
priority_queue, less> heap2; // 大根堆 priority_queue<数据类型, 存数据的结构, 数据之间的比较方式>
priority_queue, greater> heap3; // 小根堆
// 测试
for(auto x : a)
{
heap1.push(x);
heap2.push(x);
heap3.push(x);
}
while(heap1.size())
{
cout << heap1.top() << " ";
heap1.pop();
}
cout << endl;
while(heap2.size())
{
cout << heap2.top() << " ";
heap2.pop();
}
cout << endl;
while(heap3.size())
{
cout << heap3.top() << " ";
heap3.pop();
}
cout << endl;
}
int main()
{
test();
return 0;
}