堆
堆其实就是一个完全二叉树
堆分成大顶堆和小顶堆,大顶堆:节点的值 >= 其左孩子的值 且 >= 右孩子的值
,对于所有节点成立。小顶堆相反。
关于建堆初始编号造成的困惑
如果根节点编号是 0
,那么:
i
节点的父节点:(i-1)/2
i
节点的左孩子:i * 2 + 1
i
节点的右孩子:i * 2 + 2
如果根节点编号是 1
,那么:
i
节点的父节点:i / 2
i
节点的左孩子:i * 2
i
节点的右孩子:i * 2 + 1
学习博客
初始化一个小顶堆
节点
i
i
i 的两个子节点编号为
2
∗
i
2*i
2∗i 和
2
∗
i
+
1
2*i+1
2∗i+1
所以节点
i
i
i 除以
2
2
2 即可得到它的父节点
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 2e6 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
int heap[maxn];
void up(int i){// 上调编号位i的节点
if(i == 1) return;
while(i != 1){
if(heap[i] < heap[i / 2]) swap(heap[i], heap[i / 2]);
else break;
i /= 2;
}
}
void work()
{
cin >> n;
for(int i = 1; i <= n; ++i){
int x;cin >> x;
heap[i] = x;//插入尾部
up(i);// 上调
}
for(int i = 1; i <= n; ++i){
cout << heap[i] << " ";
}
}
int main()
{
ios::sync_with_stdio(0);
// int TT;cin>>TT;while(TT--)
work();
return 0;
}
L2-012 关于堆的判断 (25 分)
思路:
手写堆
题解
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 1e5 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
int heap[maxn];
map <int, int> id;// 权值映射为堆里的编号
void up(int i){
if(i == 1) return;
while(i != 1){
if(heap[i] < heap[i / 2]) swap(heap[i], heap[i / 2]);
else break;
i /= 2;
}
}
void work()
{
cin >> n >> m;
for(int i = 1; i <= n; ++i){
int x;cin >> x;
heap[i] = x;
up(i);
}
for(int i = 1; i <= n; ++i) id[heap[i]] = i;
while(m--){
int x, y;cin >> x;
string s;cin >> s;
if(s[0] == 'a'){
cin >> y >> s >> s;
if(id[x] / 2 == id[y] / 2) cout << "T\n";
else cout << "F\n";
}
else{
cin >> s;
if(s[0] == 'a'){
cin >> s >> s >> y;
if(id[y] == id[x] / 2) cout << "T\n";
else cout << "F\n";
}
else{
cin >> s;
if(s[0] == 'r'){
if(id[x] == 1) cout << "T\n";
else cout << "F\n";
}
else{
cin >> s >> y;
if(id[x] == id[y] / 2) cout << "T\n";
else cout << "F\n";
}
}
}
}
}
int main()
{
ios::sync_with_stdio(0);
// int TT;cin>>TT;while(TT--)
work();
return 0;
}