优先队列(一)——二叉堆

二叉堆的抽象数据类型:

 1 #ifndef _BinHeap_H
 2 #define ElementType int
 3 #define MinElement -1000
 4 struct HeapStruct;
 5 typedef struct HeapStruct *PriorityQueue;                   //结构体指针
 6 PriorityQueue Initialize(int MaxElements);                  //初始化一个二叉堆
 7 void Destroy(PriorityQueue H);                              //销毁二叉堆的操作
 8 void MakeEmpty(PriorityQueue H);                            //置空一个二叉堆的操作
 9 void Insert(ElementType X, PriorityQueue H);                //插入操作
10 ElementType DeleteMin(PriorityQueue H);                     //删除最小元的操作
11 ElementType FindMin(PriorityQueue H);                       //找到最小元的操作
12 int IsEmpty(PriorityQueue H);                               //判断二叉堆是否为空的操作
13 int IsFull(PriorityQueue H, int MaxElement);                //判断二叉堆是否已满的操作
14 PriorityQueue CreateHeap(ElementType a[], PriorityQueue H, int n);//利用数组创建二叉堆的操作
15 void BuildHeap(ElementType a[], PriorityQueue H, int N);    //利用数组创建二叉堆的操作
16 #endif
17
18 struct HeapStruct{
19     int Capacity;
20     int size;
21     ElementType *Elements;
22 };

二叉堆的一般操作实现:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "Heap.h"
using namespace std;

//初始化一个二叉堆
PriorityQueue Initialize(int MaxElements){
    PriorityQueue H = (PriorityQueue)malloc(sizeof(struct HeapStruct));
    H->Capacity = MinElement;
    H->size = 0;
    H->Elements = (ElementType *)malloc(MaxElements*sizeof(ElementType));
    return H;
}

//插入操作,主要的动作是——上滤
void Insert(ElementType X, PriorityQueue H){
    int i;
    for(i = ++H->size; i / 2 >= 1; i /= 2){
        if(H->Elements[i / 2] > X){
            H->Elements[i] = H->Elements[i/2];
        }
        else{
            break;
        }
    }
    H->Elements[i] = X;
}

//用一个数组创建一个二叉堆,通过反复调用Insert()操作来保证新的元素进入时的堆序性
PriorityQueue CreateHeap(ElementType a[],PriorityQueue H, int n){
    for (int i = 0; i < n; i++)
    {
        Insert(a[i], H);
    }
}

//输出整个二叉堆的所有元素,输出顺序是Elements数组的顺序
void PrintBinHeap(PriorityQueue H){
    printf("优先队列为:");
    for (int i = 1; i <= H->size; i++)
    {
        printf("\t%d", H->Elements[i]);
    }
    printf("\n");
}

//删除二叉堆堆顶的元素,即最小的那个元素;主要的操作是——下滤
ElementType DeleteMin(PriorityQueue H){
    ElementType LastElement = H->Elements[H->size--];
    ElementType MinElements = H->Elements[1];
    int i, Child;
    for(i  = 1; i * 2 <= H->size; i = Child){
        Child = i * 2;
        if(Child != H->size && H->Elements[Child + 1] < H->Elements[Child]){    //判断某个结点是否只有一个孩子结点
            Child++;
        }
        if(H->Elements[Child] < LastElement){
            H->Elements[i] = H->Elements[Child];
        }
        else{
            break;
        }
    }
    H->Elements[i] = LastElement;
    return MinElements;
}

//销毁二叉堆
void Destroy(PriorityQueue H){
    free(H->Elements);
    free(H);
}

//清空二叉堆,并返回一个空的二叉堆
void MakeEmpty(PriorityQueue H){
    free(H->Elements);
}

//判断二叉堆是否为空
int IsEmpty(PriorityQueue H){
    return H == NULL;
}

//判断二叉堆是否已满
int IsFull(PriorityQueue H, int MaxElement){
    return H->size > MaxElement;
}

ElementType FindMin(PriorityQueue H){
    return H->Elements[1];
}

//利用数组创建二叉堆的操作,只需花费线性时间O(N)
void PercolateDown(ElementType a[], int i, int N){
    int Child, Element = a[i];
    int k;
    for(k = i; k * 2 <= N; k = Child){
        Child = k * 2;
        if(Child != N && a[Child+1] < a[Child]){
            Child++;
        }
        if(Element > a[Child]){
            a[k] = a[Child];
        }
        else{
            break;
        }
    }
    a[k] = Element;
}

void BuildHeap(ElementType a[], PriorityQueue H, int N){
    for(int i = N/2; i > 0; i--){
        PercolateDown(a, i, N);
    }
    for(int i = 1; i <= N; i++){
        H->Elements[i] = a[i];
        H->size++;
    }
}

void Election()

int main(){
    PriorityQueue H;
    int n;
    printf("请输入元素个数:\n");
    scanf("%d", &n);
    ElementType a[n+1];
    printf("请输入元素,以空格分隔:\n");
    for(int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
    }
    H = Initialize(68);
    BuildHeap(a, H, n);
    PrintBinHeap(H);
    printf("%d", FindMin(H));
    system("pause");
    return 0;
}

原文地址:https://www.cnblogs.com/XiJiBaLuanXie/p/11827244.html

时间: 2024-08-27 07:17:07

优先队列(一)——二叉堆的相关文章

优先队列之二叉堆与d-堆

二叉堆简介 平时所说的堆,若没加任何修饰,一般就是指二叉堆.同二叉树一样,堆也有两个性质,即结构性和堆序性.正如AVL树一样,对堆的以此操作可能破坏者两个性质中的一个,因此,堆的操作必须要到堆的所有性质都被满足时才能终止. 结构性质 堆是一棵完全填满的二叉树,因为完全二叉树很有规律,所以它可以用一个数组表示而不需要指针.如下图所示,图2中的数组对应图1中的堆.                   图1:二叉堆                                            

算法学习 - 优先队列的二叉堆实现

PriorityQuenue 优先队列就是作业调度类的ADT,这里用二叉堆来实现. 优先队列最少有两个操作:插入(Insert)和删除最小者(DeleteMin). 插入操作图解: 图片来源:www.educity.cn 删除操作图解: 图片来源:www.cfanz.cn 代码实现: // // main.cpp // binaryHeap // // Created by Alps on 14-8-17. // Copyright (c) 2014年 chen. All rights rese

《Algorithms算法》笔记:优先队列(2)——二叉堆

二叉堆 1 二叉堆的定义 堆是一个完全二叉树结构(除了最底下一层,其他层全是完全平衡的),如果每个结点都大于它的两个孩子,那么这个堆是有序的. 二叉堆是一组能够用堆有序的完全二叉树排序的元素,并在数组中按照层级存储(不用数组的第一个位置) 2 二叉堆的性质 最大的元素在a[1] (root结点) 每个k的父亲在k/2 每个k的孩子在k*2和k*2+1 3 二叉堆的操作 3.1 上浮(孩子大于父亲)--对应插入操作 循环,每次比较自己和父亲,如果比父亲大就交换,直到root. 3.2 插入 先把元

优先队列 - 数据结构 (二叉堆)

优先队列包括二叉堆.d-堆.左式堆.斜堆.二项队列等 1.二叉堆 堆是一棵被完全填满的二叉树,有可能例外的是在底层,底层上的元素从左到右填入.这样的树称为完全二叉树. 堆序的性质:在一个堆中,对于每一个节点X,X的父亲的关键字小于(或等于)X中的关键字,根节点除外(它没有父节点).完全二叉树可以用数组实现. //关于二叉堆的头文件定义 如果要插入的元素是新的最小值,那么它将一直被推向堆顶.这样在某一个时刻,i将是1,我们就需要另Insert函数令程序跳出while循环,这个值必须保证小于或者至少

纯数据结构Java实现(6/11)(二叉堆&amp;优先队列)

堆其实也是树结构(或者说基于树结构),一般可以用堆实现优先队列. 二叉堆 堆可以用于实现其他高层数据结构,比如优先队列 而要实现一个堆,可以借助二叉树,其实现称为: 二叉堆 (使用二叉树表示的堆). 但是二叉堆,需要满足一些特殊性质: 其一.二叉堆一定是一棵完全二叉树 (完全二叉树可以用数组表示,见下面) 完全二叉树缺失的部分一定是在右下方.(每层一定是从左到右的顺序优先存放) 完全二叉树的结构,可以简单理解成按层安放元素的.(所以数组是不错的底层实现) 其二.父节点一定比子节点大 (针对大顶堆

二叉堆,优先队列,二叉树的理解

1. 二叉堆是完全二叉树,即它的N级子节点放慢之后才会去放N+1级子节点 2. 二叉堆用数组实现,每个子节点通过固定的索引找到(由完全二叉树保证) 3. 二叉堆排序只保证堆顶有效,即堆顶是最大值或最小值,是优先队列实现的不二选择 4. 二叉堆删除节点,需要重新组织堆内结构,不太高效 5. 二叉树,也叫二叉搜索树,用关系型容器实现,适用于普通的查找,排序

结构之美——优先队列基本结构(四)——二叉堆、d堆、左式堆、斜堆

实现优先队列结构主要是通过堆完成,主要有:二叉堆.d堆.左式堆.斜堆.二项堆.斐波那契堆.pairing 堆等. 1. 二叉堆 1.1. 定义 完全二叉树,根最小. 存储时使用层序. 1.2. 操作 (1). insert(上滤) 插入末尾 26,不断向上比较,大于26则交换位置,小于则停止. (2). deleteMin(下滤) 提取末尾元素,放在堆顶,不断下滤: (3). 其他操作: 都是基于insert(上滤)与deleteMin(下滤)的操作. 减小元素:减小节点的值,上滤调整堆. 增大

【转】二叉堆与优先队列

目录 1.插入 2.删除 3.查询 1.堆排序 2.用两个堆来维护一些查询第k小/大的操作 中位数 3.利用堆来维护可以“反悔的贪心” 如题,二叉堆是一种基础数据结构 事实上支持的操作也是挺有限的(相对于其他数据结构而言),也就插入,查询,删除这一类 对了这篇文章中讲到的堆都是二叉堆,而不是斜堆,左偏树,斐波那契堆什么的 我都不会啊 更新概要: 无良博主终于想起来要更新辣 upd1:更新5.2.2-对于该子目所阐述的操作“用两个堆来维护一些查询第k小/大的操作”更新了一道例题-该操作对于中位数题

二叉堆(binary heap)

堆(heap) 亦被称为:优先队列(priority queue),是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因而实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权.堆即为解决此类问题设计的一种数据结构. 本文地址:http://www.cnblogs.com/archimedes/p/binary-heap.html,转载请注明源地址. 逻辑定义 n个