Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103278
  • 博文数量: 18
  • 博客积分: 1425
  • 博客等级: 上尉
  • 技术积分: 236
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-21 20:38
文章分类
文章存档

2011年(6)

2009年(10)

2008年(2)

我的朋友

分类: C/C++

2009-03-17 15:20:59


/*-
 * Copyright (C) 2006 Jason Evans .
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 * notice(s), this list of conditions and the following disclaimer as
 * the first lines of this file unmodified other than the possible
 * addition of one or more copyright notices.
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice(s), this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************
 *
 * cpp macro implementation of red-black trees. Red-black trees are difficult
 * to explain without lots of diagrams, so little attempt is made to document
 * this code. However, an excellent discussion can be found in the following
 * book, which was used as the reference for writing this implementation:
 *
 * Introduction to Algorithms
 * Thomas H. Cormen, Charles E. Leiserson, and Ronald L. Rivest
 * MIT Press (1990)
 * ISBN 0-07-013143-0
 *
 * Some macros use a comparison function pointer, which is expected to have the
 * following prototype:
 *
 * int (compare *)( *a_a, *a_b);
 *
 * Interpretation of comparision function return values:
 *
 * -1 : a_a < a_b
 * 0 : a_a == a_b
 * 1 : a_a > a_b
 *
 * Some of the macros expand out to be quite a bit of code, so if they are
 * called in a program in more than a couple of places for a particular type, it
 * is probably a good idea to create functions that wrap the macros to keep code
 * size down.
 *
 *******************************************************************************
 */

 
/* Node structure. */
#define rb_node(a_type) struct { \
    a_type *rbn_par; \
    a_type *rbn_left; \
    a_type *rbn_right; \
    bool rbn_red; \
}
 
#define rb_node_new(a_tree, a_node, a_field) do { \
    (a_node)->a_field.rbn_par = &(a_tree)->rbt_nil; \
    (a_node)->a_field.rbn_left = &(a_tree)->rbt_nil; \
    (a_node)->a_field.rbn_right = &(a_tree)->rbt_nil; \
    (a_node)->a_field.rbn_red = false; \
} while (0)
 
/* Root structure. */
#define rb_tree(a_type) struct { \
    a_type *rbt_root; \
    a_type rbt_nil; \
}
 
#define rb_tree_new(a_tree, a_field) do { \
    (a_tree)->rbt_root = &((a_tree)->rbt_nil); \
    rb_node_new(a_tree, &(a_tree)->rbt_nil, a_field); \
} while (0)
 
#define rb_tree_nil(a_tree) (&(a_tree)->rbt_nil)
 
/* Operations. */
#define rb_root(a_tree) (a_tree)->rbt_root
 
#define rb_p_first(a_tree, a_root, a_field, r_node) do { \
    for ((r_node) = (a_root); \
         (r_node)->a_field.rbn_left != &(a_tree)->rbt_nil; \
         (r_node) = (r_node)->a_field.rbn_left); \
} while (0)
 
#define rb_p_last(a_tree, a_root, a_field, r_node) do { \
    for ((r_node) = (a_root); \
         (r_node)->a_field.rbn_right != &(a_tree)->rbt_nil; \
         (r_node) = (r_node)->a_field.rbn_right); \
} while (0)
 
#define rb_first(a_tree, a_field, r_node) \
    rb_p_first(a_tree, rb_root(a_tree), a_field, r_node)
 
#define rb_last(a_tree, a_field, r_node) \
    rb_p_last(a_tree, rb_root(a_tree), a_field, r_node)
 
#define rb_next(a_tree, a_node, a_type, a_field, r_node) do { \
    if ((a_node)->a_field.rbn_right != &(a_tree)->rbt_nil) { \
        rb_p_first(a_tree, (a_node)->a_field.rbn_right, \
             a_field, r_node); \
    } else { \
        a_type *t = (a_node); \
        (r_node) = (a_node)->a_field.rbn_par; \
        while ((r_node) != &(a_tree)->rbt_nil \
           && t == (r_node)->a_field.rbn_right) { \
            t = (r_node); \
            (r_node) = (r_node)->a_field.rbn_par; \
        } \
    } \
} while (0)
 
#define rb_prev(a_tree, a_node, a_type, a_field, r_node) do { \
    if ((a_node)->a_field.rbn_left != &(a_tree)->rbt_nil) { \
        rb_p_last(a_tree, (a_node)->a_field.rbn_left, \
            a_field, r_node); \
    } else { \
        a_type *t = (a_node); \
        (r_node) = (a_node)->a_field.rbn_par; \
        while ((r_node) != &(a_tree)->rbt_nil \
            && t == (r_node)->a_field.rbn_left) { \
            t = (r_node); \
            (r_node) = (r_node)->a_field.rbn_par; \
        } \
    } \
} while (0)
 
/* a_key is always the first argument to a_comp. */
#define rb_search(a_tree, a_key, a_comp, a_field, r_node) do { \
    int t; \
    (r_node) = (a_tree)->rbt_root; \
    while ((r_node) != &(a_tree)->rbt_nil \
        && (t = (a_comp)((a_key), (r_node))) != 0) { \
        if (t == -1) \
            (r_node) = (r_node)->a_field.rbn_left; \
        else \
            (r_node) = (r_node)->a_field.rbn_right; \
    } \
} while (0)
 
/*
 * Find a match if it exists. Otherwise, find the next greater node, if one
 * exists.
 */

#define rb_nsearch(a_tree, a_key, a_comp, a_type, a_field, r_node) do { \
    int t; \
    (r_node) = (a_tree)->rbt_root; \
    while ((r_node) != &(a_tree)->rbt_nil \
        && (t = (a_comp)((a_key), (r_node))) != 0) { \
        if (t == -1) { \
            if ((r_node)->a_field.rbn_left == \
                &(a_tree)->rbt_nil) \
                break; \
            (r_node) = (r_node)->a_field.rbn_left; \
        } else { \
            if ((r_node)->a_field.rbn_right \
                == &(a_tree)->rbt_nil) { \
                a_type *n = (r_node); \
                (r_node) = (r_node)->a_field.rbn_par; \
                while ((r_node) != &(a_tree)->rbt_nil &&\
                    n == (r_node)->a_field.rbn_right) { \
                    n = (r_node); \
                    (r_node) = \
                        (r_node)->a_field.rbn_par; \
                } \
                break; \
            } \
            (r_node) = (r_node)->a_field.rbn_right; \
        } \
    } \
} while (0)
 
#define rb_p_left_rotate(a_tree, a_node, a_type, a_field) do { \
    a_type *t = (a_node)->a_field.rbn_right; \
    (a_node)->a_field.rbn_right = t->a_field.rbn_left; \
    if (t->a_field.rbn_left != &(a_tree)->rbt_nil) \
        t->a_field.rbn_left->a_field.rbn_par = (a_node); \
    t->a_field.rbn_par = (a_node)->a_field.rbn_par; \
    if ((a_node)->a_field.rbn_par == &(a_tree)->rbt_nil) \
        (a_tree)->rbt_root = t; \
    else if ((a_node) \
        == (a_node)->a_field.rbn_par->a_field.rbn_left) \
        (a_node)->a_field.rbn_par->a_field.rbn_left = t; \
    else \
        (a_node)->a_field.rbn_par->a_field.rbn_right = t; \
    t->a_field.rbn_left = (a_node); \
    (a_node)->a_field.rbn_par = t; \
} while (0)
 
#define rb_p_right_rotate(a_tree, a_node, a_type, a_field) do { \
    a_type *t = (a_node)->a_field.rbn_left; \
    (a_node)->a_field.rbn_left = t->a_field.rbn_right; \
    if (t->a_field.rbn_right != &(a_tree)->rbt_nil) \
        t->a_field.rbn_right->a_field.rbn_par = (a_node); \
    t->a_field.rbn_par = (a_node)->a_field.rbn_par; \
    if ((a_node)->a_field.rbn_par == &(a_tree)->rbt_nil) \
        (a_tree)->rbt_root = t; \
    else if ((a_node) \
         == (a_node)->a_field.rbn_par->a_field.rbn_right) \
        (a_node)->a_field.rbn_par->a_field.rbn_right = t; \
    else \
        (a_node)->a_field.rbn_par->a_field.rbn_left = t; \
    t->a_field.rbn_right = (a_node); \
    (a_node)->a_field.rbn_par = t; \
} while (0)
 
/* a_node is always the first argument to a_comp. */
#define rb_insert(a_tree, a_node, a_comp, a_type, a_field) do { \
    /* Insert. */ \
    a_type *x = &(a_tree)->rbt_nil; \
    a_type *y = (a_tree)->rbt_root; \
    int c; \
    while (y != &(a_tree)->rbt_nil) { \
        x = y; \
        c = (a_comp)((a_node), y); \
        if (c == -1) \
            y = y->a_field.rbn_left; \
        else \
            y = y->a_field.rbn_right; \
    } \
    (a_node)->a_field.rbn_par = x; \
    if (x == &(a_tree)->rbt_nil) \
        (a_tree)->rbt_root = (a_node); \
    else if (c == -1) \
        x->a_field.rbn_left = (a_node); \
    else \
        x->a_field.rbn_right = (a_node); \
    /* Fix up. */ \
    x = (a_node); \
    x->a_field.rbn_red = true; \
    while (x != (a_tree)->rbt_root \
        && x->a_field.rbn_par->a_field.rbn_red) { \
        y = x->a_field.rbn_par; \
        if (y == y->a_field.rbn_par->a_field.rbn_left) { \
            y = y->a_field.rbn_par->a_field.rbn_right; \
            if (y->a_field.rbn_red) { \
                x->a_field.rbn_par->a_field.rbn_red = \
                    false; \
                y->a_field.rbn_red = false; \
                x->a_field.rbn_par->a_field.rbn_par \
                    ->a_field.rbn_red = true; \
                x = x->a_field.rbn_par->a_field.rbn_par;\
            } else { \
                if (x == x->a_field.rbn_par \
                    ->a_field.rbn_right) { \
                    x = x->a_field.rbn_par; \
                    rb_p_left_rotate(a_tree, x, \
                        a_type, a_field); \
                } \
                x->a_field.rbn_par->a_field.rbn_red = \
                    false; \
                x->a_field.rbn_par->a_field.rbn_par \
                    ->a_field.rbn_red = true; \
                x = x->a_field.rbn_par->a_field.rbn_par;\
                rb_p_right_rotate(a_tree, x, a_type, \
                    a_field); \
            } \
        } else { \
            y = y->a_field.rbn_par->a_field.rbn_left; \
            if (y->a_field.rbn_red) { \
                x->a_field.rbn_par->a_field.rbn_red = \
                    false; \
                y->a_field.rbn_red = false; \
                x->a_field.rbn_par->a_field.rbn_par \
                    ->a_field.rbn_red = true; \
                x = x->a_field.rbn_par->a_field.rbn_par;\
            } else { \
                if (x == x->a_field.rbn_par \
                    ->a_field.rbn_left) { \
                    x = x->a_field.rbn_par; \
                    rb_p_right_rotate(a_tree, x, \
                        a_type, a_field); \
                } \
                x->a_field.rbn_par->a_field.rbn_red = \
                    false; \
                x->a_field.rbn_par->a_field.rbn_par \
                    ->a_field.rbn_red = true; \
                x = x->a_field.rbn_par->a_field.rbn_par;\
                rb_p_left_rotate(a_tree, x, a_type, \
                    a_field); \
            } \
        } \
    } \
    (a_tree)->rbt_root->a_field.rbn_red = false; \
} while (0)
 
#define rb_remove(a_tree, a_node, a_type, a_field) do { \
    bool fixup; \
    a_type *x, *y; \
    if ((a_node)->a_field.rbn_left == &(a_tree)->rbt_nil \
        || (a_node)->a_field.rbn_right == &(a_tree)->rbt_nil) \
        y = (a_node); \
    else \
        rb_next(a_tree, a_node, a_type, a_field, y); \
    if (y->a_field.rbn_left != &(a_tree)->rbt_nil) \
        x = y->a_field.rbn_left; \
    else \
        x = y->a_field.rbn_right; \
    x->a_field.rbn_par = y->a_field.rbn_par; \
    if (y->a_field.rbn_par == &(a_tree)->rbt_nil) \
        (a_tree)->rbt_root = x; \
    else if (y == y->a_field.rbn_par->a_field.rbn_left) \
        y->a_field.rbn_par->a_field.rbn_left = x; \
    else \
        y->a_field.rbn_par->a_field.rbn_right = x; \
    if (y->a_field.rbn_red == false) \
        fixup = true; \
    else \
        fixup = false; \
    if (y != (a_node)) { \
        /* Splice y into a_node's location. */ \
        y->a_field.rbn_par = (a_node)->a_field.rbn_par; \
        y->a_field.rbn_left = (a_node)->a_field.rbn_left; \
        y->a_field.rbn_right = (a_node)->a_field.rbn_right; \
        y->a_field.rbn_red = (a_node)->a_field.rbn_red; \
        if (y->a_field.rbn_par != &(a_tree)->rbt_nil) { \
            if (y->a_field.rbn_par->a_field.rbn_left == \
                (a_node)) { \
                y->a_field.rbn_par->a_field.rbn_left = \
                    y; \
            } else { \
                y->a_field.rbn_par->a_field.rbn_right = \
                    y; \
            } \
        } else \
            (a_tree)->rbt_root = y; \
        y->a_field.rbn_right->a_field.rbn_par = y; \
        y->a_field.rbn_left->a_field.rbn_par = y; \
    } \
    rb_node_new(a_tree, a_node, a_field); \
    if (fixup) { \
        /* Fix up. */ \
        a_type *v, *w; \
        while (x != (a_tree)->rbt_root \
            && x->a_field.rbn_red == false) { \
            if (x == x->a_field.rbn_par->a_field.rbn_left) {\
                w = x->a_field.rbn_par \
                    ->a_field.rbn_right; \
                if (w->a_field.rbn_red) { \
                    w->a_field.rbn_red = false; \
                    v = x->a_field.rbn_par; \
                    v->a_field.rbn_red = true; \
                    rb_p_left_rotate(a_tree, v, \
                        a_type, a_field); \
                    w = x->a_field.rbn_par \
                        ->a_field.rbn_right; \
                } \
                if (w->a_field.rbn_left->a_field.rbn_red\
                    == false && w->a_field.rbn_right \
                    ->a_field.rbn_red == false) { \
                    w->a_field.rbn_red = true; \
                    x = x->a_field.rbn_par; \
                } else { \
                    if (w->a_field.rbn_right \
                        ->a_field.rbn_red == \
                        false) { \
                        w->a_field.rbn_left \
                            ->a_field.rbn_red \
                                = false; \
                        w->a_field.rbn_red = \
                            true; \
                        rb_p_right_rotate( \
                            a_tree, w, a_type, \
                            a_field); \
                        w = x->a_field.rbn_par \
                            ->a_field.rbn_right;\
                    } \
                    w->a_field.rbn_red \
                        = x->a_field.rbn_par \
                        ->a_field.rbn_red; \
                    x->a_field.rbn_par \
                        ->a_field.rbn_red = false; \
                    w->a_field.rbn_right \
                        ->a_field.rbn_red = false; \
                    v = x->a_field.rbn_par; \
                    rb_p_left_rotate(a_tree, v, \
                        a_type, a_field); \
                    break; \
                } \
            } \
            else \
            { \
                w = x->a_field.rbn_par \
                    ->a_field.rbn_left; \
                if (w->a_field.rbn_red) { \
                    w->a_field.rbn_red = false; \
                    v = x->a_field.rbn_par; \
                    v->a_field.rbn_red = true; \
                    rb_p_right_rotate(a_tree, v, \
                        a_type, a_field); \
                    w = x->a_field.rbn_par \
                        ->a_field.rbn_left; \
                } \
                if (w->a_field.rbn_right \
                    ->a_field.rbn_red == false && \
                    w->a_field.rbn_left->a_field.rbn_red\
                    == false) { \
                    w->a_field.rbn_red = true; \
                    x = x->a_field.rbn_par; \
                } else { \
                    if (w->a_field.rbn_left \
                        ->a_field.rbn_red \
                         == false) { \
                        w->a_field.rbn_right \
                            ->a_field.rbn_red \
                            = false; \
                        w->a_field.rbn_red = \
                            true; \
                        rb_p_left_rotate(a_tree,\
                            w, a_type, a_field);\
                        w = x->a_field.rbn_par \
                            ->a_field.rbn_left; \
                    } \
                    w->a_field.rbn_red = \
                        x->a_field.rbn_par \
                        ->a_field.rbn_red; \
                    x->a_field.rbn_par \
                        ->a_field.rbn_red = false; \
                    w->a_field.rbn_left \
                        ->a_field.rbn_red = false; \
                    v = x->a_field.rbn_par; \
                    rb_p_right_rotate(a_tree, v, \
                        a_type, a_field); \
                    break; \
                } \
            } \
        } \
        x->a_field.rbn_red = false; \
    } \
} while (0)

阅读(1250) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~