左式树

左式树是二叉堆,儿子节点的值比父亲大,特点是趋于不平衡,目的是为了合并操作,因为诸如AVL树,二叉堆等结构对于merge操作支持的很不好

零路径长:从一个节点到一个没有两个儿子的节点的最短路径长,没有儿子的节点或者有一个儿子的节点的npl是0,因为是到自己的路径长,为了方便,设计NULL节点的npl值为-1。任何一个节点的npl比它的诸儿子的npl的最小值多1。

左式树性质:

1.对于每个节点,左儿子的npl至少和右儿子的npl一样大

2.右路径是最短的路径

3.在右路径上有r个节点的左式树至少有2^{r} - 1个节点,证明用数学归纳法,一个根,两个子树应用归纳

左式树例程如下:

#ifdef _cplusplus
extern "C" {
#endif

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

struct TreeNode;
typedef struct TreeNode * PriorityQueue;
typedef int ElementType;

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))
#define DeleteMin(H) (H = DeleteMin1(H))
PriorityQueue Insert1(ElementType X, PriorityQueue H);
PriorityQueue DeleteMin1(PriorityQueue H);

struct TreeNode
{
    ElementType Element;
    PriorityQueue Left;
    PriorityQueue Right;
    int npl;
};

/* 交换H的左右子树 */
static void SwapChildren(PriorityQueue H)
{
    PriorityQueue Tmp;
    Tmp = H->Left;
    H->Left = H->Right;
    H->Right = Tmp;
}

/* 合并左式树核心例程 */
static PriorityQueue Merge1(PriorityQueue H1, PriorityQueue H2)
{
    /* 递归终止条件,此时H1是一个没有儿子的节点 */
    if (!H1->Left)
        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)
        return H2;
    if (!H2)
        return H1;

    /* 用这个方法保证小的根在第一个参数 */
    if (H1->Element < H2->Element)
        return Merge1(H1, H2);
    else
        return Merge1(H2, H1);
}

/* 左式树插入,创建一个单节点和H合并,H可以是空 */
PriorityQueue Insert1(ElementType X, PriorityQueue H)
{
    PriorityQueue SingleNode;
    SingleNode = malloc(sizeof(struct TreeNode));
    SingleNode->Element = X;
    SingleNode->Left = SingleNode->Right = NULL;
    SingleNode->npl = 0;
    H = Merge(SingleNode, H);
    return H;
}

/* 左式树合并,删除根,将左右子树合并 */
PriorityQueue DeleteMin1(PriorityQueue H)
{
    PriorityQueue Left, Right;

    if (!H)
        return NULL;

    Left = H->Left;
    Right = H->Right;
    free(H);
    return Merge(Left, Right);
}

void main()
{

}

#ifdef _cplusplus
}
#endif

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值