数据类型 - 堆
数据类型 - 堆
堆,是一种可以在极短时间复杂度中实现维护一个可以增减的排序数据结构,大体分为大根堆与小根堆。


手写做法
实现:push 函数
实操步骤:
- \(n + 1\)
- 初始化 \(p = n\),是起一个辅助效果
- 如果 \(p > 1\) 且 \(heap_{\frac{p}{2}},heap_{p}\),交换 \(heap_{\frac{p}{2}},heap_{p}\)
- \(p = \frac{p}{2}\)
- 重复执行 \(2 \sim 4 \text{ step}\)
实现:pop 函数
实操步骤:
- \(n - 1\)
- 初始化 \(p = 1\),是起一个辅助效果
- 重复执行一下步骤直到 \(p \times 2 > n\)
- 如果 \(p \times 2 + 1 > n\) 或 \(heap_{p \times 2} \le heap_{p \times 2 + 1}\),交换 \(heap_p,heap_{p \times 2}\)
- 否则交换 \(heap_p,heap_{p \times 2 + 1}\)
实现:top 函数
实操步骤:
- 返回 \(heap_1\)
实现:empty 函数
实操步骤:
- 如果 \(n = 0\),返回
True - 否则返回
False
大根堆实现
Code1
#include <iostream>
using namespace std;
#define MAXN 100005
int heap[MAXN],n;
void push(int i)
{
n++;
heap[n]=i;
int p=n;
while(p>1&&heap[p/2]>heap[p])
{
swap(heap[p/2],heap[p]);
p/=2;
}
return ;
}
void pop()
{
heap[1]=heap[n];
n--;
int p=1,t;
while(p*2<=n)
{
if(p*2+1>n||heap[p*2]<=heap[p*2+1]) t=p*2;
else t=p*2+1;
if(heap[p]>heap[t])
{
swap(heap[p],heap[t]);
p=t;
}
else break;
}
return ;
}
int top() {return heap[1];}
bool empty()
{
if(n==0) return true;
else return false;
}
int main()
{
push(3);
push(1);
push(2);
while(!empty())
{
cout<<top()<<endl;
pop();
}
return 0;
}
# output
3
2
1
小根堆实现
Code2
#include <iostream>
using namespace std;
#define MAXN 100005
int heap[MAXN],n;
void push(int i)
{
n++;
heap[n]=i;
int p=n;
while(p>1&&heap[p/2]<heap[p]) //There!
{
swap(heap[p/2],heap[p]);
p/=2;
}
return ;
}
void pop()
{
heap[1]=heap[n];
n--;
int p=1,t;
while(p*2<=n)
{
if(p*2+1>n||heap[p*2]>=heap[p*2+1]) t=p*2; //There!
else t=p*2+1;
if(heap[p]<heap[t]) //And There!
{
swap(heap[p],heap[t]);
p=t;
}
else break;
}
return ;
}
int top() {return heap[1];}
bool empty()
{
if(n==0) return true;
else return false;
}
int main()
{
push(3);
push(1);
push(2);
while(!empty())
{
cout<<top()<<endl;
pop();
}
return 0;
}
# output
1
2
3
C++ Stl 做法
以下展示常规操作。
Code3
#include <iostream>
#include <queue>
using namespace std;
int main()
{
priority_queue<int> q; //定义(C++ 默认大根堆)如果是要求实现小根堆请写:
//priority_queue<int,vector<int>,greater<int> > q;
q.push(3); //push, 表示压入。
q.push(1); //push, 表示压入。
q.push(2); //push, 表示压入。
while(!q.empty())
{
cout<<q.top()<<endl; //top, 表示优先队列中的堆顶。
q.pop(); //pop, 表示删除堆顶。
}
return 0;
}
# output
3
2
1

浙公网安备 33010602011771号