zoukankan      html  css  js  c++  java
  • 15. 二项队列

    fatal.h

    #include <stdio.h>
    #include <stdlib.h>
    
    #define Error(Str)        FatalError(Str)
    #define FatalError(Str)   fprintf(stderr, "%s
    ", Str), exit(1)
    

    binomial.h

    typedef long ElementType;
    #define Infinity (30000L)
    
    #ifndef _BinHeap_H
    #define _BinHeap_H
    
    #define MaxTrees (14)   /* Stores 2^14 -1 items */
    #define Capacity (16383)
    
    struct BinNode;
    typedef struct BinNode *BinTree;
    struct Collection;
    typedef struct Collection *BinQueue;
    
    BinQueue Initialize(void);
    void Destroy(BinQueue H);
    BinQueue MakeEmpty(BinQueue H);
    BinQueue Insert(ElementType Item, BinQueue H);
    ElementType DeleteMin(BinQueue H);
    BinQueue Merge(BinQueue H1, BinQueue H2);
    ElementType FindMin(BinQueue H);
    int IsEmpty(BinQueue H);
    int IsFull(BinQueue H);
    #endif
    

    binomial.c

    #include "binomial.h"
    #include "fatal.h"
    
    typedef struct BinNode *Position;
    
    struct BinNode
    {
        ElementType Element;
        Position    LeftChild;
        Position    NextSibling;
    };
    
    struct Collection
    {
        int CurrentSize;
        BinTree TheTrees[MaxTrees];
    };
    
    BinQueue Initialize(void)
    {
        BinQueue H;
        int i;
    
        H = malloc(sizeof(struct Collection));
        if (H == NULL)
            FatalError("Out of space!!!");
        H->CurrentSize = 0;
        for (i = 0; i < MaxTrees; i++)
            H->TheTrees[i] = NULL;
        return H;
    }
    
    static void DestroyTree(BinTree T)
    {
        if (T != NULL)
        {
            DestroyTree(T->LeftChild);
            DestroyTree(T->NextSibling);
            free(T);
        }
    }
    
    void Destroy(BinQueue H)
    {
        int i;
    
        for (i = 0; i < MaxTrees; i++)
            DestroyTree(H->TheTrees[i]);
    }
    
    BinQueue MakeEmpty(BinQueue H)
    {
        int i;
    
        Destroy(H);
        for (i = 0; i < MaxTrees; i++)
            H->TheTrees[i] = NULL;
        H->CurrentSize = 0;
    
        return H;
    }
    
    /* Not optimized for O(1) amortized performance */
    BinQueue Insert(ElementType Item, BinQueue H)
    {
        BinTree NewNode;
        BinQueue OneItem;
    
        NewNode = malloc(sizeof(struct BinNode));
        if (NewNode == NULL)
            FatalError("Out of space!!!");
        NewNode->LeftChild = NewNode->NextSibling = NULL;
        NewNode->Element = Item;
    
        OneItem = Initialize();
        OneItem->CurrentSize = 1;
        OneItem->TheTrees[0] = NewNode;
    
        return Merge(H, OneItem);
    }
    
    ElementType DeleteMin(BinQueue H)
    {
        int i, j;
        int MinTree;   /* The tree with the minimum item */
        BinQueue DeletedQueue;
        Position DeletedTree, OldRoot;
        ElementType MinItem;
    
        if (IsEmpty(H))
        {
            Error("Empty binomial queue");
            return -Infinity;
        }
    
        MinItem = Infinity;
        for (i = 0; i < MaxTrees; i++)
        {
            if (H->TheTrees[i] &&
                H->TheTrees[i]->Element < MinItem)
            {
                /* Update minimum */
                MinItem = H->TheTrees[i]->Element;
                MinTree = i;
            }
        }
    
        DeletedTree = H->TheTrees[MinTree];
        OldRoot = DeletedTree;
        DeletedTree = DeletedTree->LeftChild;
        free(OldRoot);
    
        DeletedQueue = Initialize();
        DeletedQueue->CurrentSize = (1 << MinTree) - 1;
        for (j = MinTree - 1; j >= 0; j--)
        {
            DeletedQueue->TheTrees[j] = DeletedTree;
            DeletedTree = DeletedTree->NextSibling;
            DeletedQueue->TheTrees[j]->NextSibling = NULL;
        }
    
        H->TheTrees[MinTree] = NULL;
        H->CurrentSize -= DeletedQueue->CurrentSize + 1;
    
        Merge(H, DeletedQueue);
        return MinItem;
    }
    
    ElementType FindMin(BinQueue H)
    {
        int i;
        ElementType MinItem;
    
        if (IsEmpty(H))
        {
            Error("Empty binomial queue");
            return 0;
        }
    
        MinItem = Infinity;
        for (i = 0; i < MaxTrees; i++)
        {
            if (H->TheTrees[i] &&
                H->TheTrees[i]->Element < MinItem)
                MinItem = H->TheTrees[i]->Element;
        }
    
        return MinItem;
    }
    
    int IsEmpty(BinQueue H)
    {
        return H->CurrentSize == 0;
    }
    
    int IsFull(BinQueue H)
    {
        return H->CurrentSize == Capacity;
    }
    
    /* Return the result of merging equal-sized T1 and T2 */
    BinTree CombineTrees(BinTree T1, BinTree T2)
    {
        if (T1->Element > T2->Element)
            return CombineTrees(T2, T1);
        T2->NextSibling = T1->LeftChild;
        T1->LeftChild = T2;
        return T1;
    }
    
    /* Merge two binomial queues */
    /* Not optimized for early termination */
    /* H1 contains merged result */
    BinQueue Merge(BinQueue H1, BinQueue H2)
    {
        BinTree T1, T2, Carry = NULL;
        int i, j;
    
        if (H1->CurrentSize + H2->CurrentSize > Capacity)
            Error("Merge would exceed capacity");
    
        H1->CurrentSize += H2->CurrentSize;
        for (i = 0, j = 1; j <= H1->CurrentSize; i++, j *= 2)
        {
            T1 = H1->TheTrees[i]; T2 = H2->TheTrees[i];
    
            switch (!!T1 + 2 * !!T2 + 4 * !!Carry)
            {
            case 0: /* No trees */
            case 1: /* Only H1 */
                break;
            case 2: /* Only H2 */
                H1->TheTrees[i] = T2;
                H2->TheTrees[i] = NULL;
                break;
            case 4: /* Only Carry */
                H1->TheTrees[i] = Carry;
                Carry = NULL;
                break;
            case 3: /* H1 and H2 */
                Carry = CombineTrees(T1, T2);
                H1->TheTrees[i] = H2->TheTrees[i] = NULL;
                break;
            case 5: /* H1 and Carry */
                Carry = CombineTrees(T1, Carry);
                H1->TheTrees[i] = NULL;
                break;
            case 6: /* H2 and Carry */
                Carry = CombineTrees(T2, Carry);
                H2->TheTrees[i] = NULL;
                break;
            case 7: /* All three */
                H1->TheTrees[i] = Carry;
                Carry = CombineTrees(T1, T2);
                H2->TheTrees[i] = NULL;
                break;
            }
        }
        return H1;
    }
    
  • 相关阅读:
    elasticseacth基础操作--QueryBuilders的使用
    并发编程(八)并发安全
    redis集群 相关
    并发编程(七)线程池
    PMP--综合考试知识点,持续更新中。。。
    常用正则表达式
    测试计划
    ACC(Attribute Component Capability) 即特质,组件,能力
    LockScreen
    Custom Window
  • 原文地址:https://www.cnblogs.com/typewriter/p/6384821.html
Copyright © 2011-2022 走看看