`
haoningabc
  • 浏览: 1482942 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

生成二叉树和红黑树的helloworld(5) (转)

 
阅读更多
参考http://blog.csdn.net/manuscola/article/details/8635525
https://github.com/killinux/rbtree
https://github.com/manuscola/rbtree

#include "rbtree.h"
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>

void delete_case1(struct rbtree* tree,struct rbtree_node* node);
void delete_case2(struct rbtree* tree,struct rbtree_node* node);
void delete_case3(struct rbtree* tree,struct rbtree_node* node);
void delete_case4(struct rbtree* tree,struct rbtree_node* node);
void delete_case5(struct rbtree* tree,struct rbtree_node* node);
void delete_case6(struct rbtree* tree,struct rbtree_node* node);

static inline enum rb_color get_color(struct rbtree_node* node)
{
    if(node == NULL)
        return RB_BLACK;
    else
        return node->color;    
}

static inline void set_color(enum rb_color color,struct rbtree_node* node)
{
    assert(node != NULL);
    node->color = color;
}

static inline struct rbtree_node*  get_parent(struct rbtree_node* node)
{
    assert(node != NULL);
    return node->parent;
}

static inline void set_parent(struct rbtree_node* parent,struct rbtree_node* node)
{
    assert(node != NULL);
    node->parent = parent;
}

static int is_root(struct rbtree_node* node)
{
    assert(node != NULL);
    return (get_parent(node)==NULL);
}

static inline int is_black(struct rbtree_node* node)
{
    assert(node != NULL);
    return (get_color(node) == RB_BLACK);
}

static inline int is_red(struct rbtree_node *node)
{
    assert(node != NULL);
    return (get_color(node) == RB_RED);
}

struct rbtree_node* sibling(rbtree_node* node)
{
    assert (node != NULL);
    assert (node->parent != NULL); /* Root node has no sibling */
    if (node == node->parent->left)
        return node->parent->right;
    else
        return node->parent->left;
}
static inline rbtree_node* get_min(struct rbtree_node* node)
{
    assert(node != NULL);
    while(node->left)
    {
        node =  node->left;
    }
    return node;
}

static inline rbtree_node* get_max(struct rbtree_node* node)
{
    assert(node != NULL);
    while(node->right)
    {
        node = node->right;
    }
    return node;
}

struct rbtree_node* rbtree_min(struct rbtree *tree)
{
    if(tree->root == NULL)
        return NULL;
    else
    {
        return get_min(tree->root);
    }
}

struct rbtree_node* rbtree_max(struct rbtree* tree)
{
    if(tree->root == NULL)
        return NULL;
    else
    {
        return get_max(tree->root);
    }
}

struct rbtree_node* rbtree_prev(struct rbtree_node* node)
{
    assert(node != NULL);
    if(node->left)
    {
        return get_max(node->left);
    }
    else
    {
        struct rbtree_node* parent;
        while ((parent = get_parent(node)) && parent->left == node)
        {
            node = parent;
        }
        return parent;
    }
}

struct rbtree_node* rbtree_next(struct rbtree_node* node)
{
    assert(node != NULL);

    if(node->right)
        return get_min(node->right);
    else
    {
        struct rbtree_node* parent = NULL;
        while((parent = get_parent(node)) != NULL && parent->right == node)
        {
            node = parent;
        }
        return parent;
    }
}

struct rbtree_node* rbtree_createnode(void *key, void* data)
{
    struct rbtree_node* newnode = malloc(sizeof(struct rbtree_node));
    if(newnode == NULL)
        return NULL;

    newnode->key = key;
    newnode->data = data;
    newnode->parent = NULL;
    newnode->left = NULL;
    newnode->right = NULL;
    return newnode;
}

/*
static inline int compare(void* key_a,void* key_b)
{
    if(key_a > key_b)
        return 1;
    else if(key_a == key_b)
        return 0;
    else
        return -1;
}*/

struct rbtree_node* do_lookup(void* key,
        struct rbtree* tree,
        struct rbtree_node** pparent)
{
    struct rbtree_node *current = tree->root;

    while(current)
    {
        int ret = tree->compare(current->key,key);
        if(ret == 0 )
            return  current;
        else
        {
            if(pparent != NULL)
            {
                *pparent = current;
            }
            if (ret < 0 )
                current = current->right;
            else
                current = current->left;
        }
    }
    return NULL;

}

void*  rbtree_lookup(struct rbtree* tree,void* key)
{
    assert(tree != NULL) ;
    struct rbtree_node* node;
    node = do_lookup(key,tree,NULL);
    return node == NULL ?NULL:node->data;
}

static void set_child(struct rbtree* tree,struct rbtree_node* node,struct rbtree_node* child)
{
    int ret = tree->compare(node->key,child->key);
    assert(ret != 0);

    if(ret > 0)
    {
        node->left = child;
    }
    else{
        node->right = child;
    }
}

static void rotate_left(struct rbtree_node* node,struct rbtree* tree)
{
    struct rbtree_node* p = node;
    struct rbtree_node* q = node->right;
    struct rbtree_node* parent = node->parent;
    if(parent == NULL)
    {
        tree->root = q;
    }
    else
    {
        if(parent->left == p)
            parent->left = q;
        else
            parent->right = q;
    }
    set_parent(parent,q);
    set_parent(q,p);

    p->right = q->left;
    if(q->left)
        set_parent(p,q->left);
    q->left = p;

}

static void rotate_right(struct rbtree_node *node, struct rbtree *tree)
{
    struct rbtree_node *p = node;
    struct rbtree_node *q = node->left; /* can't be NULL */
    struct rbtree_node *parent = get_parent(p);

    if (!is_root(p)) {
        if (parent->left == p)
            parent->left = q;
        else
            parent->right = q;
    } else
        tree->root = q;
    set_parent(parent, q);
    set_parent(q, p);

    p->left = q->right;
    if (p->left)
        set_parent(p, p->left);
    q->right = p;
}



struct rbtree* rbtree_init(rbtree_cmp_fn_t compare)
{
    struct rbtree* tree = malloc(sizeof(struct rbtree));
    if(tree == NULL)
        return NULL;
    else
    {
        tree->root = NULL;
        tree->compare = compare;
    }
    
    return tree;
}
struct rbtree_node* __rbtree_insert(struct rbtree_node* node,struct rbtree *tree)
{
    struct rbtree_node* samenode=NULL;
    struct rbtree_node*parent=NULL;

    samenode = do_lookup(node->key,tree,&parent);
    if(samenode != NULL)
        return samenode;

    node->left = node->right = NULL;
    set_color(RB_RED,node);
    set_parent(parent,node);

    if(parent == NULL)
        tree->root = node;
    else
    {
        set_child(tree,parent,node);
    }

    while((parent = get_parent(node)) != NULL && parent->color == RB_RED)
    {
        struct rbtree_node* grandpa = get_parent(parent);//grandpa must be existed 
        //because root is black ,and parent is red,
        //parent can not be root of tree. and parent is red,so grandpa must be black
        if(parent == grandpa->left)
        {
            struct rbtree_node* uncle = grandpa->right;
            if(uncle && get_color(uncle) == RB_RED)
            {
                set_color(RB_RED,grandpa);
                set_color(RB_BLACK,parent);
                set_color(RB_BLACK,uncle);
                node = grandpa;
            }
            else
            {
                if(node == parent->right )
                {
                    rotate_left(parent,tree);
                    node = parent;
                    parent = get_parent(parent);
                }
                set_color(RB_BLACK,parent);
                set_color(RB_RED,grandpa);
                rotate_right(grandpa,tree);
            }

        }
        else
        {
            struct rbtree_node* uncle = grandpa->left;
            if(uncle && uncle->color == RB_RED)
            {
                set_color(RB_RED,grandpa);
                set_color(RB_BLACK,parent);
                set_color(RB_BLACK,uncle);
                node = grandpa;
            }
            else
            {
                if(node == parent->left)
                {
                    rotate_right(parent,tree);
                    node = parent;
                    parent = get_parent(node);
                }
                set_color(RB_BLACK, parent);
                set_color(RB_RED, grandpa);
                rotate_left(grandpa, tree);
            }
        }
    }

    set_color(RB_BLACK,tree->root);
    return NULL;
}

int  rbtree_insert(struct rbtree *tree, void*  key,void* data)
{
    struct rbtree_node * node = rbtree_createnode(key,data);
    struct rbtree_node* samenode = NULL;
    if(node == NULL)
        return -1;
    else
        samenode = __rbtree_insert(node,tree);
    if(samenode != NULL)
        return -2;
    return 0;
}


void replace_node(struct rbtree* t, rbtree_node *oldn, rbtree_node* newn) 
{
    if (oldn->parent == NULL)
    {
        t->root = newn;
    }
    else
    {
        if (oldn == oldn->parent->left)
            oldn->parent->left = newn;
        else
            oldn->parent->right = newn;
    }
    if (newn != NULL)
    {
        newn->parent = oldn->parent;
    }
}

void delete_case1(struct rbtree* tree, struct rbtree_node* node)
{
    if(node->parent == NULL)
        return ;
    else
        delete_case2(tree,node);
}

void delete_case2(struct rbtree* tree, struct rbtree_node* node)
{
    if(get_color(sibling(node)) == RB_RED)
    {
        node->parent->color = RB_RED;
        sibling(node)->color = RB_BLACK;
        if(node == node->parent->left)
        {
            rotate_left(node->parent,tree);
        }
        else
        {
            rotate_right(node->parent,tree);
        }
    }
    delete_case3(tree,node);
}

void delete_case3(struct rbtree* tree,struct rbtree_node* node)
{
    if(node->parent->color == RB_BLACK &&
            get_color(sibling(node)) == RB_BLACK &&
            get_color(sibling(node)->right) == RB_BLACK &&
            get_color(sibling(node)->left) == RB_BLACK)
    {
        sibling(node)->color = RB_RED;
        delete_case1(tree, node->parent);
    }
    else
    {
        delete_case4(tree, node);
    }

}

void delete_case4(struct rbtree* t, struct rbtree_node* n) 
{
    if (get_color(n->parent) == RB_RED &&
            get_color(sibling(n)) ==RB_BLACK &&
            get_color(sibling(n)->left) ==RB_BLACK &&
            get_color(sibling(n)->right) == RB_BLACK)
    {
        sibling(n)->color =RB_RED; //sibling's two son is black ,so it can changed to red
        n->parent->color = RB_BLACK;
    }
    else
        delete_case5(t, n);
}

void delete_case5(struct rbtree *t, rbtree_node *n)
{
    if (n == n->parent->left &&
            get_color(sibling(n)) ==RB_BLACK &&
            get_color(sibling(n)->left) == RB_RED &&
            get_color(sibling(n)->right) == RB_BLACK)
    {
        sibling(n)->color = RB_RED;
        sibling(n)->left->color =RB_BLACK;
        rotate_right(sibling(n),t);
    }
    else if (n == n->parent->right &&
            get_color(sibling(n)) == RB_BLACK &&
            get_color(sibling(n)->right) == RB_RED &&
            get_color(sibling(n)->left) == RB_BLACK)
    {
        sibling(n)->color = RB_RED;
        sibling(n)->right->color = RB_BLACK;
        rotate_left(sibling(n),t);
    }
    delete_case6(t, n);
}

void delete_case6(struct rbtree*  t, rbtree_node* n)
{
    sibling(n)->color = get_color(n->parent);
    n->parent->color = RB_BLACK;
    if (n == n->parent->left) 
    {
        assert (get_color(sibling(n)->right) == RB_RED);
        sibling(n)->right->color = RB_BLACK;
        rotate_left(n->parent,t);
    }
    else
    {
        assert (get_color(sibling(n)->left) == RB_RED);
        sibling(n)->left->color = RB_BLACK;
        rotate_right( n->parent,t);
    }
}
void __rbtree_remove(struct rbtree_node* node,struct rbtree* tree)
{
    struct rbtree_node *left = node->left;
    struct rbtree_node* right = node->right;
    struct rbtree_node* child = NULL;
    if(left != NULL && right != NULL )
    {
        struct rbtree_node* next = get_min(right);
        node->key = next->key;
        node->data = next->data;
        node = next;
    }

    assert(node->left == NULL || node->right == NULL);
    child = (node->right == NULL ? node->left : node->right);
    if(get_color(node) == RB_BLACK)
    {
        set_color(get_color(child),node);
        delete_case1(tree,node);
    }
    replace_node(tree,node,child);
    if(node->parent == NULL && child != NULL)//node is root,root should be black
        set_color(RB_BLACK,child);
    free(node);
}

int  rbtree_remove(struct rbtree* tree,void *key)
{
    struct rbtree_node* node = do_lookup(key,tree,NULL);
    if(node == NULL)
        return -1;
    else
        __rbtree_remove(node,tree);
    return 0;
}

rbtree.h
#ifndef __RBTREE_H__
#define __RBTREE_H__

enum rb_color
{
    RB_BLACK,
    RB_RED,
};

typedef struct rbtree_node
{
    struct rbtree_node* parent;
    struct rbtree_node* left;
    struct rbtree_node* right;
    enum rb_color color;
    void*  key;
    void *data;
}rbtree_node;

typedef int (*rbtree_cmp_fn_t)(void *key_a,  void *key_b);
typedef struct rbtree
{
    struct rbtree_node* root;
    rbtree_cmp_fn_t compare; 
}rbtree;

struct rbtree* rbtree_init(rbtree_cmp_fn_t fn);
int  rbtree_insert(struct rbtree *tree, void *key,void* data);
void*  rbtree_lookup(struct rbtree* tree,void *key);
int  rbtree_remove(struct rbtree* tree,void *key);
#endif
分享到:
评论

相关推荐

    排序二叉树, 数据结构中的hello world

    为了解决排序二叉树可能倾斜的问题,引入了平衡二叉树的概念,如AVL树和红黑树。这些平衡二叉树通过旋转等操作保持树的平衡,确保最坏情况下的操作效率也能保持在O(log n)。 **五、总结** 排序二叉树是数据结构中...

    搜狐2012.9.15校园招聘会笔试题.docx

    7. 红黑树、AVL树是特定类型的二叉搜索树,满足二叉树定义。B树是多路搜索树,不是严格意义上的二叉树。B+树是B树的一种变体,也有多个分支。答案是AC。 8. 在二维数组`A[2][3]`中,`A[1][0]`表示第二行第一列的...

    校招面试题目

    - **平衡保障方法**:常见的平衡二叉树类型包括AVL树和红黑树。AVL树通过旋转操作来维持树的平衡,而红黑树则通过对节点着色并遵循特定规则来维护平衡。这些技术的核心在于,在进行插入或删除操作后,通过一系列的...

    一些公司笔试的数据结构和C++字符串操作

    2. 高级数据结构:如树(二叉树、平衡树如AVL和红黑树)、图、堆(最大堆和最小堆)、哈希表等。 3. 操作:插入、删除、查找、排序等,以及它们的时间复杂度分析。 4. 图算法:如深度优先搜索(DFS)和广度优先搜索...

    《数据结构与算法分析》

    树结构如二叉树、红黑树、AVL树等在搜索、排序等方面有广泛应用;图则用于模拟现实世界中的复杂关系,如网络拓扑、社交网络等。哈希表则提供了快速查找的能力,其查找时间复杂度可达到O(1)。 其次,算法是解决问题...

    code.zip

    这里可能涉及二叉树、平衡树(如AVL树或红黑树)、堆(如二叉堆)等。Python中可以使用类来实现这些数据结构,同时可能包含插入、删除、查找等操作。 4. **branch.py**:分支可能与树的分支有关,也可能是版本控制...

    Packt.Learn.Data.Structures.and.Algorithms.with.Golang.1789618509.rar

    这本书会介绍各种经典的数据结构,如数组、链表、栈、队列、树(二叉树、平衡树如AVL树和红黑树)、图以及哈希表等。理解这些数据结构的特性和操作方式对于编写高效代码至关重要。 算法是解决问题的步骤或方法,是...

    浙江大学2015-2016高级数据结构与算法分析试卷及答案

    这是因为红黑树在经过插入和删除操作之后需要通过旋转和重新着色来保持树的平衡。 在使用3盘进行2路合并排序时,不同的原始分布可能影响到合并的效率。具体到(34,21)和(27,28)这两个分布,前者在某些情况下可能会有...

    Java数据结构概述图表

    - 常见的树形结构包括二叉树、红黑树等。Java中没有直接提供树结构的支持,但可以通过自定义类实现。 - 示例:`TreeNode root = new TreeNode(1);` 7. **图(Graph)** - 图是由顶点集和边集构成的非线性数据...

    structuri_de_date

    11. 树形结构(Tree Structure):Python可以用来构建二叉树、红黑树等树结构,常用于搜索和排序算法。虽然没有内置的树数据结构,但可以通过自定义类来实现。 12. 哈希表(Hash Table):Python的字典底层实现就是...

    数据结构与算法分析(C++版)(第二版)习题参考答案

    - **平衡二叉搜索树(Balanced Binary Search Trees)**:例如AVL树和红黑树,它们能够保持较好的平衡性,从而提高查找效率。 **知识点7:排序算法** - **内部排序**:所有待排序的元素都保存在内存中进行排序的方法...

    Data-Structures-in-Python:这些是用python编写的用于自学习的数据结构列表

    12. 树(Tree):虽然Python没有内置的树数据结构,但可以通过类来构建二叉树、红黑树等。树常用于搜索、排序和组织复杂数据。 13. 图(Graph):图数据结构可以用来表示网络、关系等复杂结构,Python的`networkx`库...

Global site tag (gtag.js) - Google Analytics