二叉堆

Posted 100001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉堆相关的知识,希望对你有一定的参考价值。

二叉堆是一种插入、删除、查询最值的数据结构。它其实是一棵满足“堆性质”的完全二叉树,树上的每个节点带有一个权值。

一、若树中的任意一个节点的权值都小于等于其父节点的权值,则称该二叉树满足“大根堆性质”。

二、若树中的任意一个节点的权值都大于等于其父节点的权值,则称该二叉树满足“小根堆性质”。

以下是小根堆的相关操作:
1.插入操作以及调整

 

 1 int heap[size],n;
 2 void up(int p){ //插入到末尾,再向上调整
 3     while(p>1){
 4         if(heap[p]<heap[p/2]){
 5             swap(heap[p],heap[p/2]);
 6             p=p/2;
 7         }
 8         else
 9             break;
10     }
11 }
12 void insert(int val){
13     heap[++n]=val;
14     up(n);
15 }

 

2.获取堆顶元素

1 int GetTop(){
2     return heap[1];
3 }

3.删除堆顶元素

Extract操作把堆顶从二叉堆中移除。我们把堆顶heap[1]与存储在数组末尾的节点heap[n]交换,然后移除数组末尾的节点(令n减小1),最后把堆顶元素通过交换的方式向下调整,直至满足堆性质。其时间复制度为堆的深度,即O(logN)。

 1 void down(int p){
 2     int s=2*p;
 3     if(s<=n){
 4         if(s<n&&heap[s]>heap[s++]) s++;
 5         if(heap[s]<heap[p]) {
 6             swap(heap[s],heap[p]);
 7             p=s,s=2*p;
 8         }
 9         else
10             break;
11     }
12 }
13 void Extract(){
14     heap[1]=heap[n--];
15     down(1);
16 }

4.删除位置为P的节点。该操作与Extract相似,先把heap[p]与heap[n]交换,然后令n 减小1。注意此时heap[p]既有可能需要向下调整,也有可能需要向上调整,需要分别进行检查和处理。时间复杂度为O(logN)。

1 void Remove(int k){
2     heap[k]=heap[n--];
3     up(k),down(k);
4 }

相关题目:

1.牛客网 rating

输入

5 5
2000 2100 2200 2300 2350
1900
1500
2200
2700
2000

 

输出

10900.00
10675.00
10912.50
11281.25
11231.25

 

说明

解析:每次选择当前帐号最小的rating,就能确保每场比赛之后的rating之和最大。代码如下:

 1 #include<iostream>
 2 using namespace std;
 3 int a[100005],n;
 4 double heap[100005];
 5 void up(int p){
 6     while(p>1){
 7         if(heap[p]<heap[p/2]) {
 8             swap(heap[p],heap[p/2]);
 9             p=p/2;
10         }
11         else
12             break;
13     }
14 }
15 void Insert(double val){ //val必须为double
16     heap[++n]=val;
17     up(n);
18 }
19 double Gettop(){ //函数返回值为double
20     return heap[1];
21 }
22 void down(int p){
23     int s=p*2;
24     while(s<=n){
25         if(s<n&&heap[s]>heap[s+1]) s++;
26         if(heap[s]<heap[p]) 
27             {
28             swap(heap[s],heap[p]);
29             p=s,s=2*p;}
30         else
31             break;}
32 }
33 void Extract(){
34     heap[1]=heap[n--];
35     down(1);
36 }
37 int num,m;
38 double ans;
39 int main(){
40     cin>>num>>m;
41     for(int i=1;i<=num;i++)
42     {
43         cin>>a[i];
44         ans=ans+a[i];
45         Insert(a[i]);
46     }
47     for(int i=1;i<=m;i++){
48         double x;
49         int y;
50         double rating;
51         x=Gettop();
52         ans=ans-x;
53         cin>>y;
54         rating=(x+y)/2.0;
55         Extract();
56         Insert(rating);
57         ans=ans+rating;
58         printf("%0.2lf\\n",ans);
59     }
60     return 0;
61 }

 

以上是关于二叉堆的主要内容,如果未能解决你的问题,请参考以下文章

合并果子(二叉堆)

龙珠游戏(二叉堆)

Java 数据结构 & 算法宁可累死自己, 也要卷死别人 13 二叉堆

Java 数据结构 & 算法宁可累死自己, 也要卷死别人 13 二叉堆

二叉堆(彻底整明白堆排序)

二叉堆