您的位置:首页 > 编程语言 > C语言/C++

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

2017-04-03 14:27 861 查看

左式堆

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

零路径长

把任意节点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_H

struct 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) {

}


可以自行到网上找一些左式堆的图片加深一下理解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 数据结构