堆以及优先队列

#include<iostream>
using namespace std;
int A[]={0,4,1,3,2,16,9,10,14,8,7};
int left(int i){
    return 2*i;
}
int right(int i){
    return 2*i+1;
}
int parent(int i){
    return i/2;
}
void heap(int i){
    int l=left(i);
    int r=right(i);
    int larget;
    if(l<=10&&A[l]>A[i]){
        larget=l;
    }
    else
        larget=i;
    if(r<=10&& A[r]>A[larget]){
        larget=r;
    }
    if(larget!=i){
        int t=A[larget];
        A[larget]=A[i];
        A[i]=t;
        heap(larget);

    }
}
int main(){
    //heap(2); //观察从第二个位置开始不符合最大堆的规定
    //重建堆:
    for(int i=10/2+1;i>=1;i--){
        heap(i);
    }
    for(int i=1;i<=10;i++){
        cout<<A[i]<<endl;
    }
    system("pause");
    return 0;
}

重建堆,从非叶子节点的节点开始,自下而上地重建最大堆!
是维护最大堆方法的调用。
堆排序算法:

}

堆以及优先队列的操作:
#include<iostream>
using namespace std;
//int a[]={0,16,4,10,14,7,9,3,2,8,1};
int a[]={0,4,1,3,2,16,9,10,14,8,7};
int len=0;
int left(int i){
    return 2*i;
}
int right(int i){
    return 2*i+1;
}
int partent(int i){
    return i/2;
}
int length(){
        for(int i=1;;i++){
        if(a[i]!=0)
            len++;
        else
        break;
    }
        return len;
}
//维护堆的性质,n为出现不符合最大堆的位置,小于俩孩子结点的情况
int heap(int n){
    int l,r,larget;
    l=left(n);
    r=right(n);
    if(a[n]<a[l]&&l<=len){
        larget=l;
    }else
        larget=n;
    if(a[r]>a[larget]&&r<=len)
        larget=r;
    if(larget!=n){
        int t=a[n];
        a[n]=a[larget];
        a[larget]=t;
        heap(larget);
    }
    return 0;
}
//建堆
void buildheap(){
    //从叶子结点开始
    for(int i=len/2;i>0;i--){
        heap(i);
    }
}
//堆排序算法:最大元素为a[1],拿走最大元素,长度减一
void heapsort(){
    buildheap();   //进行排序,使最大元素位于第一位
    int leng=len;
    for(int i=leng;i>=2;i--){
        int t=a[1];
        a[1]=a[i];
        a[i]=t;
        len--;
        heap(1);
    }
}
//以下的方法为优先队列
//得到最大元素:对于最大堆来说,最大元素为第一个
int Maximun(){
    return a[1];
}
//得到最大元素并去掉,
int extact(){
    int max=a[1];
    a[1]=a[len];
    len--;
    heap(1);
    return max;
}
//insert(x,k)  将x位置的数据增大k,增大到k可能会导致最大堆发生变化
void insert(int x,int k){
    a[x]=k;
    if(x!=1){
        while((x>1)&&(a[x]>a[partent(x)])){
        //大于父母结点的孩子,这种情况比较简单,向上替换父母结点即可
            int t=a[x];
            a[x]=a[partent(x)];
            a[partent(x)]=t;
            x=partent(x);
        }
    }
}
//将key插入集合中
void insertkey(int key){
    len+=1;
    a[len]=-1000;
    insert(len,key);
}
int main(){
    length();
    int l=len;
    //heap(2);
    buildheap();
    //insert(2,20);
    //cout<<Maximun()<<endl;
    //cout<<extact()<<"==="<<endl;
    //heapsort();
    insertkey(15);
    for(int i=1;i<=l+1;i++){
        cout<<a[i]<<endl;
    }
    system("pause");
    return 0;
}
时间: 2024-10-21 14:24:58

堆以及优先队列的相关文章

堆与优先队列

当我们需要高效的完成以下操作时: 1.插入一个元素 2.取得最小(最大)的数值,并且删除 能够完成这种操作的数据结构叫做优先队列 而能够使用二叉树,完成这种操作的数据结构叫做堆(二叉堆) 堆与优先队列的时间复杂度: 若共有n个元素,则可在O(logn)的时间内完成上述两种操作 堆的结构如下图: 堆最重要的性质就是儿子的值一定不小于父亲的值,且堆从上到下,从左到右紧密排列. 堆的操作: 当我们希望向堆中插入元素时,堆的内部会进行如下操作(以插入元素3为例): (1.在堆的末尾插入该值) (2.不断

堆和优先队列

1 二叉堆和优先队列的概念 1.1 二叉堆 二叉堆堆是一个数组,它可以被看成一个近似的完全二叉树,树上每一个结点对应数组中的一个元素.除了最底层外,该树是完全充满的,而且是从左到右填充.表示堆的数组A包括两个属性:A.length给出数组元素的个数,A.heap_size表示有多少个堆元素存储在该数组中,这里,0<=A.heap_size<=A.length. 如下图所示: 堆可以分成两种:最大堆和最小堆.在最大堆中,任何节点的值都大于等于其孩子的值,故根节点是数组中的最大数所在节点.反之,最

[ACM] POJ 1442 Black Box (堆,优先队列)

Black Box Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7099   Accepted: 2888 Description Our Black Box represents a primitive database. It can save an integer array and has a special i variable. At the initial moment Black Box is empt

数据结构-堆实现优先队列(java)

队列的特点是先进先出.通常都把队列比喻成排队买东西,大家都很守秩序,先排队的人就先买东西.但是优先队列有所不同,它不遵循先进先出的规则,而是根据队列中元素的优先权,优先权最大的先被取出.这就很像堆的特征:总是移除优先级最高的根节点. 重点:优先级队列,是要看优先级的,谁的优先级更高,谁就先得到权限.不分排队的顺序! 上篇文章解释了堆的概念实现,现在用堆实现优先队列: //最大堆 import java.util.ArrayList; public class Heap<E extends Com

最小堆(优先队列)基本概念,即一个完整建立,插入,删除代码

堆(优先队列)priority queue特殊的队列,取出元素的顺序是依照元素的优先权(关键字)大小,而出元素进入队列的先后顺序操作:查找最大值(最小值),删除(最大值) 数组:链表:有序数组:有序链表: 采用二叉搜索树? NO 采用完全二叉树 YES堆的连个特性结构性:用数组表示的完全二叉树:有序性:任一结点的关键字是其字树所有结点的最大值(或最小值) 最大堆(MaxHeap)也称大顶堆:最大值 最小堆(MinHeap)也称"小顶堆":最小值 从根节点到任意结点路径上结点序列的有序性

【转】用大顶堆实现优先队列

队列的特点是先进先出.通常都把队列比喻成排队买东西,大家都很守秩序,先排队的人就先买东西.但是优先队列有所不同,它不遵循先进先出的规则,而是根据队列中元素的优先权,优先权最大的先被取出.这就很像堆的特征:总是移除优先级最高的根节点. 重点:优先级队列,是要看优先级的,谁的优先级更高,谁就先得到权限.不分排队的顺序! 用堆实现优先队列: //最大堆 import java.util.ArrayList; public class Heap<E extends Comparable>{ priva

0038数据结构之堆和优先队列

优先队列:出队顺序和入队顺序无关,而是和优先级有关(优先级高的先出队) 如果使用普通线性结构或者顺序线性结构实现优先队列,出队或者入队总有一方是O(n)级别的:如果使用堆实现优先队列,能使入队和出队的时间复杂度都是O(logn),效率是极高的. 二叉堆是一颗完全二叉树,不一定是满二叉树,但是确实节点的那部分一定是在整棵树的右下侧.满足的规律:1)根节点最大, 2)确实节点的那部分在整棵树的右下侧.(低层次的节点不一定大于高层次的节点) 下图是一颗最大堆: 可以用数组存储: 从数组1位置开始存储:

数据结构之基于堆的优先队列

优先队列的最重要的操作:删除最大元素(或最小)和插入元素.数据结构二叉堆能够很好的实现队列的基本操作.二叉堆的结点按照层级顺序放入数组,用长度为N+1的私有数组pq来表示一个大小为N的堆(堆元素放在pq[1]至pq[N]之间,为方便计数,未使用pq[0]),跟节点在位置1,它的子结点在位置2和3,以此类推.位置k的节点的父节点位置为k/2,它的两个子节点位置分别为2k和2k+1.当一颗二叉树的每个节点都大于等于它的两个子节点时,称为大根堆.当一颗二叉树的每个节点都小于等于它的两个子节点时,称为小

4538: [Hnoi2016]网络 链剖 + 堆(优先队列) / 整体二分

GDOI之后写的第一道题.看到之后没什么感觉(是我太弱,中途一度想用kpm之前在某道题上用过的链表的方法.想了想应该不可能.) 好!让我们来分析这道题吧!首先简化模型,它是要求维护树上的一些路径,支持添加和修改,要求不经过某个点的路径的最大权值(不经过某个点,我一度想到了动点分,虽然我还不会). 我们可以先考虑在链上(其实仔细一想,如果链上的你会做,那么树上的大多数情况下便是多个了链剖而已吧!)的情况.在链上,有一些区间覆盖,要求没有覆盖某个点的区间的最大权值.那么我们接着想如果询问2询问了一个