堆的基本操作

大顶堆

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
#include<algorithm>

using namespace std;
const int maxn=10007;

int heap[maxn];
int n;
///堆调整
void AdjustHeap(int root)
{
    int lchild=2*root+1;
    int rchild=2*root+2;
    int temp=heap[root];

    while(lchild<n)
    {
        if(rchild<n && heap[rchild]>heap[lchild])
            lchild++;
        if(heap[lchild]<=temp)
            break;
        heap[root]=heap[lchild];
        root=lchild;
        lchild=2*root+1;
        rchild=2*root+2;
    }
    heap[root]=temp;
}

/*插入函数,  将要插入的数字首先加入到该二叉树最后的一个节点,
自底而上调整*/
void InsertHeap(int num)
{
    int child=n;
    int root=(child-1)/2;
    heap[child]=num;

    while(root>=0 && child!=0)
    {
        if(heap[root]>num)
            break;
        heap[child]=heap[root];
        child=root;
        root=(child-1)/2;
    }
    heap[child]=num;
    n++;
}

/*删除函数,对于最小堆和最大堆而言,删除是针对于根节点而言。
将二叉树的最后一个节点替换到根节点,然后自顶向下调整。*/
void DeleteHeap()
{
    heap[0]=heap[n-1];
    n--;
    AdjustHeap(0);
}

void BuildHeap()
{
    for(int i=(n-2)/2; i>=0; i--)
        AdjustHeap(i);
}
void Display()
{
    for(int i=0; i<n; i++)
        printf("%d%c", heap[i], i==n-1?‘\n‘:‘ ‘);
}

int main()
{
    while(~scanf("%d", &n))
    {
        for(int i=0; i<n; i++)
            scanf("%d", &heap[i]);
        BuildHeap();
        Display();

        int a;
        scanf("%d", &a);
        InsertHeap(a);
        Display();

        DeleteHeap();
        Display();
    }
    return 0;
}
/*
6
16 7 3 20 17 8
30
*/

小顶堆

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
#include<algorithm>

using namespace std;
const int maxn=10007;

int heap[maxn];
int n;
///堆调整
void AdjustHeap(int root)
{
    int lchild=2*root+1;
    int rchild=2*root+2;
    int temp=heap[root];

    while(lchild<n)
    {
        if(rchild<n && heap[rchild]<heap[lchild])
            lchild++;
        if(heap[lchild]>=temp)
            break;
        heap[root]=heap[lchild];
        root=lchild;
        lchild=2*root+1;
        rchild=2*root+2;
    }
    heap[root]=temp;
}

/*插入函数,  将要插入的数字首先加入到该二叉树最后的一个节点,
自底而上调整*/
void InsertHeap(int num)
{
    int child=n;
    int root=(child-1)/2;
    heap[child]=num;

    while(root>=0 && child!=0)
    {
        if(heap[root] <= num)
            break;
        heap[root]=heap[child];
        child=root;
        root=(child-1)/2;
    }
    heap[child]=num;
    n++;

}

/*删除函数,对于最小堆和最大堆而言,删除是针对于根节点而言。
将二叉树的最后一个节点替换到根节点,然后自顶向下调整。*/
void DeleteHeap()
{
    heap[0]=heap[n-1];
    n--;
    AdjustHeap(0);
}

void BuildHeap()
{
    for(int i=(n-2)/2; i>=0; i--)
        AdjustHeap(i);
}
void Display()
{
    for(int i=0; i<n; i++)
        printf("%d%c", heap[i], i==n-1?‘\n‘:‘ ‘);
}

int main()
{
    while(~scanf("%d", &n))
    {
        for(int i=0; i<n; i++)
            scanf("%d", &heap[i]);
        BuildHeap();
        Display();

        int a;
        scanf("%d", &a);
        InsertHeap(a);
        Display();

        DeleteHeap();
        Display();
    }
    return 0;
}
/*
6
16 7 3 20 17 8
30
*/
时间: 2024-11-05 13:38:47

堆的基本操作的相关文章

数据结构-----堆的基本操作和应用

(一)用仿函数实现大堆小堆 堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构. 堆结构的二叉树存储是 最大堆:每个父节点的都大于孩子节点. 最小堆:每个父节点的都小于孩子节点. 仿函数(functor),就是使一个类的使用看上去象一个函数.其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了.在实现大,小堆的过程中,有些功能的的代码,会在不同的成员函数中用到,想复用这些代码,有两种途径. 1)公共的函数,这是一个解决方法,不过函数用到的一些变量,就可

支持删除任意元素以及一些其他基本操作的堆

一个黑科技,不知道是谁发明的(好像也有些年代了?) 其实这个黑科技的本质就是一个大根堆,不同的是 它支持删除堆内任意元素,同时也支持堆的基本操作 code 代码如下: struct Heap{ priority_queue<int> q1,q2; inline void push(int x){q1.push(x);} inline void erase(int x){q2.push(x);} inline void pop(){for(;q2.size()&&q1.top()

通用的最小堆(最大堆)D-ary Heap

听说有一种最小(大)堆,不限于是完全二叉树,而是完全D叉树,名为D-ary Heap(http://en.wikipedia.org/wiki/D-ary_heap).D可以是1,2,3,4,100,对于优先队列该有的功能都没有问题. 动手写一个D-ary Heap,应该不难.简单起见,不考虑像STL一样通过template传入Comp类,下面的实现要求T类型重载了operator <和operator >. template<class T> class DaryHeap { s

poj2442 堆

题意:给你n*m的矩阵,然后每行取一个元素,组成一个包含n个元素的序列,一共有n^m种序列, 让你求出序列和最小的前n个序列的序列和. 先介绍下堆的基本操作: int arr[N]; make_heap(arr+1,arr+N);//对数组arr建堆,堆里第一个元素为最大值 pop_heap(arr+1,arr+N+1);//将第一个元素与最后一个元素交换 push_heap(arr+1,arr+N+1);//录入元素 sort_heap(arr+1,arr+N+1);//排序 思路:用普通方法

堆之左式堆和斜堆

d-堆 类似于二叉堆,但是它有d个儿子,此时,d-堆比二叉堆要浅很多,因此插入操作更快了,但是相对的删除操作更耗时.因为,需要在d个儿子中找到最大的,但是很多算法中插入操作要远多于删除操作,因此,这种加速是现实的. 除了不能执行find去查找一般的元素外,两个堆的合并也很困难. 左式堆 左式堆可以有效的解决上面说的堆合并的问题.合并就涉及插入删除,很显然使用数组不合适,因此,左式堆使用指针来实现.左式堆和二叉堆的区别:左式堆是不平衡的.它两个重要属性:键值和零距离 零距离(英文名NPL,即Nul

数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉搜索树.红黑树.线索二叉树,它们在解决实际问题中有着非常重要的应用.本文主要从概念和一些基本操作上进行分类和总结. 一.概念总揽 (1) 堆 堆(heap order)是一种特殊的表,如果将它看做是一颗完全二叉树的层次序列,那么它具有如下的性质:每个节点的值都不大于其孩子的值,或每个节点的值都不小于其孩子的值

数据结构-堆

堆(英语:Heap),是一种拥有像树那样的特殊数据结构,或者理解为具有优先级的树.它的特点是父节点的值大于(或小于)两个子节点的值(分别称为大顶堆和小顶堆).它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等.堆通常是一个可以被看做一棵树的数组(或ArrayList)对象.常见的堆有二叉堆.二项堆.斐波那契堆等. 二叉堆(Binary heap) 二叉堆是一种特殊的堆,实为二叉树的一种:是完全二叉树或者是近似完全二叉树.二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子

转载:数据结构 左式堆

简介 设计一种堆结构像二叉堆那样高效的支持合并操作而且只使用一个数组似乎很困难.原因在于,合并似乎需要把一个数组拷贝到另一个数组中去,对于相同大小的堆,这将花费O(N).正因为如此,所有支持高效合并的高级数据结构都需要使用指针. 像二叉堆那样,左式堆也有结构性和堆序性.不仅如此,左式堆也是二叉树,它和二叉堆之间的唯一区别在于:左式堆不是理想平衡的,而实际上是趋向于非常不平衡. 左式堆性质 把任意节点X的零路径长(null path length, NPL)Npl(X)定义为从X到一个没有两个儿子

基本数据结构——堆(Heap)的基本概念及其操作

基本数据结构――堆的基本概念及其操作 小广告:福建安溪一中在线评测系统 Online Judge 在我刚听到堆这个名词的时候,我认为它是一堆东西的集合... 但其实吧它是利用完全二叉树的结构来维护一组数据,然后进行相关操作,一般的操作进行一次的时间复杂度在 O(1)~O(logn)之间. 可谓是相当的引领时尚潮流啊(我不信学信息学的你看到log和1的时间复杂度不会激动一下下)!. 什么是完全二叉树呢?别急着去百度啊,要百度我帮你百度: 若设二叉树的深度为h,除第 h 层外,其它各层 (1-h-1