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

优先队列包括二叉堆、d-堆、左式堆、斜堆、二项队列等

1、二叉堆

堆是一棵被完全填满的二叉树,有可能例外的是在底层,底层上的元素从左到右填入。这样的树称为完全二叉树。

堆序的性质:在一个堆中,对于每一个节点X,X的父亲的关键字小于(或等于)X中的关键字,根节点除外(它没有父节点)。完全二叉树可以用数组实现。

//关于二叉堆的头文件定义

如果要插入的元素是新的最小值,那么它将一直被推向堆顶。这样在某一个时刻,i将是1,我们就需要另Insert函数令程序跳出while循环,这个值必须保证小于或者至少等

于堆中的任何值,我们称之为标记。

#ifndef BITHEAP_H_INCLUDED
#define BITHEAP_H_INCLUDED

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
struct HeapStruct;
typedef struct HeapStruct *PriorityQueue;

PriorityQueue BitHeap_Init(int max_elements);
void BitHeap_Insert(ElementType x, PriorityQueue H);
ElementType BitHeap_Delete(PriorityQueue H);
void BitHeap_Show(PriorityQueue H);
int BitHeap_Free(PriorityQueue H);

#endif // BITHEAP_H_INCLUDED

//二叉堆中的功能函数的定义

#include "bitheap.h"

struct HeapStruct
{
    int Capacity;
    int Size;
    ElementType *Elements;
};

static void print_err(char *str);
static int IsFull(PriorityQueue H);
static int IsEmpty(PriorityQueue H);

PriorityQueue BitHeap_Init(int max_elements)
{
    PriorityQueue H;

    H = (PriorityQueue)malloc(sizeof(struct HeapStruct));
    if(H == NULL)
        print_err("no space for H in BitHeap");
    H->Elements = (ElementType *)malloc((max_elements+1) * sizeof(ElementType));
    H->Elements[0] = (1<<31);
    if(H->Elements == NULL)
        print_err("no space for H->Elements in BitHeap");

    H->Capacity = max_elements;
    H->Size = 0;

    return H;
}

void BitHeap_Insert(ElementType x, PriorityQueue H)
{
    int i;

    if(IsFull(H))
    {
        printf("the heap is full\n");
        return;
    }

    for(i = ++H->Size; H->Elements[i/2] > x; i /= 2)
        H->Elements[i] = H->Elements[i/2];
    H->Elements[i] = x;
}

ElementType BitHeap_Delete(PriorityQueue H)
{
    ElementType min_val, last_val;
    int i, child;

    if(IsEmpty(H))
    {
        printf("the bitheap is empty\n");
        return (1<<31);
    }

    min_val = H->Elements[1];
    last_val = H->Elements[H->Size--];
    for(i = 1; 2*i < H->Size; i = child)
    {
        child = 2 * i;
        if(child != H->Size && (H->Elements[child+1] < H->Elements[child]))
            child++;
        if(last_val > H->Elements[child])
            H->Elements[i] = H->Elements[child];
        else
            break;
    }
    H->Elements[i] = last_val;

    return min_val;
}

void BitHeap_Show(PriorityQueue H)
{
    int i;

    if(H != NULL)
    {
        for(i = 1; i <= H->Size; i++)
            printf("%d ", H->Elements[i]);
    }
    printf("\n");
}

int BitHeap_Free(PriorityQueue H)
{
    if(H != NULL)
    {
        free(H->Elements);
        free(H);
    }
    return 1;
}

/*
* flowing function is used by function in bitheap.c
*/
static int IsFull(PriorityQueue H)
{
    return (H->Size == H->Capacity);
}
static int IsEmpty(PriorityQueue H)
{
    return (H->Size == 0);
}
static void print_err(char *str)
{
    perror(str);
    exit(-1);
}

//关于二叉堆的测试函数 main.c

#include <stdio.h>
#include <stdlib.h>

#include "bitheap.h"

int main()
{
    PriorityQueue H;

    H = BitHeap_Init(15);
    BitHeap_Insert(4, H);
    BitHeap_Insert(2, H);
    BitHeap_Insert(7, H);
    BitHeap_Insert(3, H);
    BitHeap_Insert(12, H);
    BitHeap_Insert(8, H);

    BitHeap_Show(H);

    BitHeap_Delete(H);
    BitHeap_Show(H);

    if(BitHeap_Free(H))
        printf("\nfree the bitheap is ok.\n");

    return 0;
}

2、d-堆是二叉堆的简单推广,它恰像一个二叉堆,只是所有的节点都有d个儿子(可以说二叉堆是2-堆)

3、优先队列还包括了左式堆、斜堆、二项队列等。

可以参考《数据结构与算法分析-C语言描述》第6章 - 优先队列(堆)

时间: 2024-10-07 04:54:14

优先队列 - 数据结构 (二叉堆)的相关文章

优先队列之二叉堆与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

浅析基础数据结构-二叉堆

如题,二叉堆是一种基础数据结构 事实上支持的操作也是挺有限的(相对于其他数据结构而言),也就插入,查询,删除这一类 对了这篇文章中讲到的堆都是二叉堆,而不是斜堆,左偏树,斐波那契堆什么的 我都不会啊 一.堆的性质 1.堆是一颗完全二叉树 2.堆的顶端一定是“最大”,最小”的,但是要注意一个点,这里的大和小并不是传统意义下的大和小,它是相对于优先级而言的,当然你也可以把优先级定为传统意义下的大小,但一定要牢记这一点,初学者容易把堆的“大小”直接定义为传统意义下的大小,某些题就不是按数字的大小为优先

基本数据结构——二叉堆

迅速补档,为A*做一下铺垫… 概念定义 二叉堆就是一个支持插入.删除.查询最值的数据结构.他其实是一棵完全二叉树.那么堆一般分为大根堆和小根堆 大根堆 树中的任意一个节点的权值都小于或者等于其父节点的权值,则称该二叉树满足大根堆性质. 小根堆 树中的任意一个节点的权值都大于或者等于其父节点的权值,则称该二叉树满足小根堆性质. 习惯用法 一般习惯把堆用数组保存.才用父子二倍的编号方式.即:对于某一个节点x,其左儿子节点为2*x,右儿子节点为x*2+1 支持功能及代码实现 Insert插入 向二叉堆

POJ 2010 - Moo University - Financial Aid 初探数据结构 二叉堆

考虑到数据结构短板严重,从计算几何换换口味= = 二叉堆 简介 堆总保持每个节点小于(大于)父亲节点.这样的堆被称作大根堆(小根堆). 顾名思义,大根堆的数根是堆内的最大元素. 堆的意义在于能快速O(1)找到最大/最小值,并能持续维护. 复杂度 push() = O(logn); pop() = O(logn); BinaryHeap() = O(nlogn); 实现 数组下标从1开始的情况下,有 Parent(i) = i >> 1 LChild(i) = i << 1 RChi

数据结构 二叉堆 &amp; 堆排序

二叉堆,是一个满二叉树,满足堆的性质.即父节点大于等于子节点(max heap)或者是父节点小于等于子节点(min heap).二叉堆的如上性质常用于优先队列(priority queue)或是用于堆排序. 由于max heap 与min heap类似,下文只针对min heap进行讨论和实现. 如上图,是根据字母的ASCII码建立的最小堆. 我们用数组对满二叉树采用宽度优先遍历存储堆结构,如下图所示: 从数组下标1开始存储堆,这样的处理方式可以得到如下性质: 1.堆中的每个父节点k,他的两个子

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

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

数据结构--二叉堆与堆排序

二叉堆的概念 二叉堆,BinaryHeap,是二叉树中的常见的一种结构.通常以最大堆和最小堆的形式呈现.最大堆指的是父节点大于等于孩子节点的value值,也就是说对于最大堆而言,根元素是二叉堆最大的元素.最小堆的概念是与最大堆的概念是相似的.下图是最大堆的示意图: 二叉堆和排序之间的联系 二叉堆最显著的特征就是根元素是二叉树元素间最大的或者最小的.因此每次将二叉树最大或者最小的元素取出来,同时保证每次进行这样的操作后,剩下的元素依然可以保持二叉堆的性质,这样迭代这个过程,就可以完成排序的目的.

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

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