欢迎光临
我们一直在努力

hb是拿什么语言斐波那契堆(一)之 图文解析 和 C语言的实现

/**
 * C语言实现的斐波那契堆
 *
 * @author skywang
 * @date 2014/04/05
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include "fibonacci_heap.h"

#if 0
#define LOG2(x) ({ 
        unsigned int _i = 0; 
        __asm__("bsr %1, %0" : "=r" (_i) : "r" ((x))); 
        _i; })
#else   // 注意:通过gcc编译时,要添加 -lm 选项。
#define LOG2(x) ((log((double)(x))) / (log(2.0)))
#endif

static FibNode *fib_heap_search(FibHeap *heap, Type key);

/* 
 * 将node从双链表移除
 */
static void fib_node_remove(FibNode *node)
{
    node->left->right = node->right;
    node->right->left = node->left;
}

/*
 * 将"单个节点node"加入"链表root"之前
 *   a …… root
 *   a …… node …… root
 *
 * 注意: 此处node是单个节点,而root是双向链表
*/
static void fib_node_add(FibNode *node, FibNode *root)
{
    node->left        = root->left;
    root->left->right = node;
    node->right       = root;
    root->left        = node;
}

/*
 * 将双向链表b链接到双向链表a的后面
 *
 * 注意: 此处a和b都是双向链表
*/
static void fib_node_cat(FibNode *a, FibNode *b)
{
    FibNode *tmp;

    tmp            = a->right;
    a->right       = b->right;
    b->right->left = a;
    b->right       = tmp;
    tmp->left      = b;
}

/*
 * 创建斐波那契堆
 */
FibHeap* fib_heap_make()

    heap->keyNum = 0;
    heap->maxDegree = 0;
    heap->min = NULL;
    heap->cons = NULL;

    return heap;
}

/*
 * 创建斐波那契堆的节点
 */
static FibNode* fib_node_make(Type key)

    node->key    = key;
    node->degree = 0;
    node->left   = node;
    node->right  = node;
    node->parent = NULL;
    node->child  = NULL;

    return node;
}

/*
 * 将节点node插入到斐波那契堆heap中
 */
static void fib_heap_insert_node(FibHeap *heap, FibNode *node)

    heap->keyNum++;
}

/* 
 * 新建键值为key的节点,并将其插入到斐波那契堆中
 */
void fib_heap_insert_key(FibHeap *heap, Type key)

/*
 * 将h1, h2合并成一个堆,并返回合并后的堆
 */
FibHeap* fib_heap_union(FibHeap *h1, FibHeap *h2)

    if((h1->min) == NULL)                // h1无"最小节点"
    {
        h1->min = h2->min;
        h1->keyNum = h2->keyNum;
        free(h2->cons);
        free(h2);
    }
    else if((h2->min) == NULL)           // h1有"最小节点" && h2无"最小节点"
    {
        free(h2->cons);
        free(h2);
    }                                   // h1有"最小节点" && h2有"最小节点"
    else

    return h1;
}

/*
 * 将"堆的最小结点"从根链表中移除,
 * 这意味着"将最小节点所属的树"从堆中移除!
 */
static FibNode *fib_heap_remove_min(FibHeap *heap)

    min->left = min->right = min;

    return min;
}

/*
 * 将node链接到root根结点
 */
static void fib_heap_link(FibHeap * heap, FibNode * node, FibNode *root)

/* 
 * 创建fib_heap_consolidate所需空间
 */
static void fib_heap_cons_make(FibHeap * heap)

/* 
 * 合并斐波那契堆的根链表中左右相同度数的树
 */
static void fib_heap_consolidate(FibHeap *heap)

            fib_heap_link(heap, y, x);    // 将y链接到x中
            heap->cons[d] = NULL;
            d++;
        }
        heap->cons[d] = x;
    }
    heap->min = NULL;

    // 将heap->cons中的结点重新加到根表中
    for (i=0; i<D; i++)

        }
    }
}

/*
 * 移除最小节点,并返回移除节点后的斐波那契堆
 */
FibNode* _fib_heap_extract_min(FibHeap *heap)

    // 将min从根链表中移除
    fib_node_remove(min);
    // 若min是堆中唯一节点,则设置堆的最小节点为NULL;
    // 否则,设置堆的最小节点为一个非空节点(min->right),然后再进行调节。
    if (min->right == min)
        heap->min = NULL;
    else
    {
        heap->min = min->right;
        fib_heap_consolidate(heap);
    }
    heap->keyNum--;

    return min;
}

void fib_heap_extract_min(FibHeap *heap)

/*
 * 在斐波那契堆heap中是否存在键值为key的节点;存在返回1,否则返回0。
 */
int fib_heap_get_min(FibHeap *heap, Type *pkey)

/* 
 * 修改度数
 */
static void renew_degree(FibNode *parent, int degree)

/* 
 * 将node从父节点parent的子链接中剥离出来,
 * 并使node成为"堆的根链表"中的一员。
 */
static void fib_heap_cut(FibHeap *heap, FibNode *node, FibNode *parent)

/* 
 * 对节点node进行"级联剪切"
 *
 * 级联剪切:如果减小后的结点破坏了最小堆性质,
 *     则把它切下来(即从所在双向链表中删除,并将
 *     其插入到由最小树根节点形成的双向链表中),
 *     然后再从"被切节点的父节点"到所在树根节点递归执行级联剪枝
 */
static void fib_heap_cascading_cut(FibHeap *heap, FibNode *node) 

}

/* 
 * 将斐波那契堆heap中节点node的值减少为key
 */
static void fib_heap_decrease(FibHeap *heap, FibNode *node, Type key)

    node->key = key;
    parent = node->parent;
    if (parent!=NULL && node->key < parent->key)
    {
        // 将node从父节点parent中剥离出来,并将node添加到根链表中
        fib_heap_cut(heap, node, parent);
        fib_heap_cascading_cut(heap, parent);
    }

    // 更新最小节点
    if (node->key < heap->min->key)
        heap->min = node;
}

/* 
 * 将斐波那契堆heap中节点node的值增加为key
 */
static void fib_heap_increase(FibHeap *heap, FibNode *node, Type key)

    // 将node每一个儿子(不包括孙子,重孙,...)都添加到"斐波那契堆的根链表"中
    while (node->child != NULL)

    node->degree = 0;
    node->key = key;

    // 如果node不在根链表中,
    //     则将node从父节点parent的子链接中剥离出来,
    //     并使node成为"堆的根链表"中的一员,
    //     然后进行"级联剪切"
    // 否则,则判断是否需要更新堆的最小节点
    parent = node->parent;
    if(parent != NULL)
    {
        fib_heap_cut(heap, node, parent);
        fib_heap_cascading_cut(heap, parent);
    }
    else if(heap->min == node)

    }
}

/* 
 * 更新二项堆heap的节点node的键值为key
 */
void _fib_heap_update(FibHeap *heap, FibNode *node, Type key)

void fib_heap_update(FibHeap *heap, Type oldkey, Type newkey)

/*
 * 在最小堆root中查找键值为key的节点
 */
static FibNode* fib_node_search(FibNode *root, Type key)

        else

        t = t->right;
    } while (t != root);

    return p;
}

/*
 * 在斐波那契堆heap中查找键值为key的节点
 */
static FibNode *fib_heap_search(FibHeap *heap, Type key)

/*
 * 在斐波那契堆heap中是否存在键值为key的节点。
 * 存在返回1,否则返回0。
 */
int fib_heap_contains(FibHeap *heap, Type key)
{
    return fib_heap_search(heap,key)!=NULL ? 1: 0;
}

/*
 * 删除结点node
 */
static void _fib_heap_delete(FibHeap *heap, FibNode *node)
{
    Type min = heap->min->key;
    fib_heap_decrease(heap, node, min-1);
    _fib_heap_extract_min(heap);
    free(node);
}

void fib_heap_delete(FibHeap *heap, Type key)

/* 
 * 销毁斐波那契堆
 */
static void fib_node_destroy(FibNode *node)
 while(node != start);
}

void fib_heap_destroy(FibHeap *heap)
{
    fib_node_destroy(heap->min);
    free(heap->cons);
    free(heap);
}

/*
 * 打印"斐波那契堆"
 *
 * 参数说明:
 *     node       -- 当前节点
 *     prev       -- 当前节点的前一个节点(父节点or兄弟节点)
 *     direction  --  1,表示当前节点是一个左孩子;
 *                    2,表示当前节点是一个兄弟节点。
 */
static void _fib_print(FibNode *node, FibNode *prev, int direction)
 while(node != start);
}

void fib_print(FibHeap *heap)
 while (p != heap->min);
    printf("
");
}
赞(0)
未经允许不得转载:上海聚慕医疗器械有限公司 » hb是拿什么语言斐波那契堆(一)之 图文解析 和 C语言的实现

登录

找回密码

注册