左式堆的简单实现(C语言描述)

来源:互联网 发布:java 判断char为空 编辑:程序博客网 时间:2024/05/21 07:12

左式堆

左式堆是优先队列的一种实现,它的目的主要是为了解决二叉堆的合并问题.(你将在后面看到左式堆是如何用递归来优美地进行合并的)

零路径长

把任意节点X的零路径长(null path length, NPL) Npl(X) 定义为从X到一个没有两个儿子的节点的最短路径长。因此,具有0个或1个儿子的节点的Npl值为0,而Npl(NULL)=-1。注意,任意节点的零路径长比它的各个儿子节点的最小值多1。

堆序性质

左式堆的性质是:对于堆中的每一个节点X,左儿子的零路径长至少与右儿子的零路径长一样大。因此,下图1中,左边的二叉树是左式堆,而右边的二叉树则不是。这个性质使左式堆明显更偏重于使树向左增加深度,左式堆的名称也由此而来。

代码实现

头文件

#ifndef LEFTHEAP_LEFTHEAP_H#define LEFTHEAP_LEFTHEAP_Hstruct TreeNode;typedef struct TreeNode *PriorityQueue;typedef long long ElementType;/* Minmal set of priority queue operations *//* Note that nodes will be shared among several *//* leftlist heaps after a merge; the user must *//* make sure to not use the old leftist heaps */PriorityQueue Initialize(void);ElementType FindMin(PriorityQueue H);int IsEmpty(PriorityQueue H);PriorityQueue Merge(PriorityQueue H1, PriorityQueue H2);#define Insert(X, H)(H = Insert1((X),H))PriorityQueue Insert1(ElementType X, PriorityQueue H);PriorityQueue DeleteMin1(PriorityQueue H);#endif //LEFTHEAP_LEFTHEAP_H

实现

#include "LeftHeap.h"#include <stdio.h>#include <stdlib.h>struct TreeNode {    ElementType Element;    PriorityQueue Left;    PriorityQueue Right;    int Npl;};int IsEmpty(PriorityQueue H) {    return H->Left == NULL && H->Right->Right == NULL;}static void SwapChildren(PriorityQueue pNode) {    PriorityQueue tmp = malloc(sizeof(struct TreeNode));    *tmp = *(pNode->Left);    *(pNode->Left) = *(pNode->Right);    *(pNode->Right) = *(tmp);}static PriorityQueue Merge1(PriorityQueue H1, PriorityQueue H2) {    if (H1->Left == NULL)        H1->Left = H2;    else {        H1->Right = Merge(H1->Right, H2);        if (H1->Left->Npl < H1->Right->Npl)            SwapChildren(H1);        H1->Npl = H1->Right->Npl + 1;    }    return H1;}PriorityQueue Merge(PriorityQueue H1, PriorityQueue H2) {    if (H1 == NULL)        return H2;    if (H2 == NULL)        return H1;    if (H1->Element < H2->Element)        return Merge1(H1, H2);    else        return Merge1(H2, H1);}void FatalError(char *message) {    printf("%s\n", message);    exit(1);}PriorityQueue Insert1(ElementType X, PriorityQueue H) {    PriorityQueue SingleNode;    SingleNode = malloc(sizeof(struct TreeNode));    if (SingleNode == NULL) {        FatalError("Out of space!!!");    } else {        SingleNode->Element = X;        SingleNode->Npl = 0;        SingleNode->Left = SingleNode->Right = NULL;        H = Merge(SingleNode, H);    }    return H;}void Error(char *message) {    printf("%s\n", message);}/* DeleteMin1 returns the new tree *//* To get the minmum, use FindMin *//* This is for convenience */PriorityQueue DeleteMin1(PriorityQueue H) {    PriorityQueue LeftHeap, RightHeap;    if (IsEmpty(H)) {        Error("Priority queue is empty");        return H;    }    LeftHeap = H->Left;    RightHeap = H->Right;    free(H);    return Merge(LeftHeap, RightHeap);}ElementType FindMin(PriorityQueue H) {    return H->Element;}PriorityQueue Initialize(void) {}

可以自行到网上找一些左式堆的图片加深一下理解

0 0
原创粉丝点击