红黑树插入与删除 算法实现+代码(一)

要实现红黑树节点的插入删除,得先实现二叉树节点插入删除,在这基础上加入红黑树调整算法。


今天早上编写了二叉树的节点删除代码。结果如下


实践经验:

1.要删除节点,得先遍历出节点位置,我用数组存放遍历出来的结果。然后删除结果中倒数第三个数字时,遇到了困难:

(1)刚开始直接用mid_travel算法遍历,发现递归的时候,要传递数组指针,且让指针地址增加,不好处理。

(2)然后我加入了get_tree_array函数,想通过“指针的指针”来存指针,以为记住最开始的数组指针地址,然后让指针在递归的时候,自行递增。还是失败了。这样无法保证递归的时候,数组的下标位置。在递归的时候,很难判断什么时候加1,如果要做这步,还得统计子树的左右子树数目,然后根据子节点数目增加当前节点的指针地址。这样很繁琐。

(3)于是,我加入了suffix(数组下标),这就解决了递归的时候,判断指针位置的繁琐处理。

2.很多操作用独立函数代替,不但逻辑看起来会更清晰,而且可以重用,一举两得。函数看起来很多,其实都是互相嵌套的,其实可以用一个函数写完。


红黑树插入算法实践经验

(1)昨天写好了红黑树算法,调试了一下午,发现打印出来的树不对。

 原因1是NULL改为哨兵节点Nil,很多判断要用哨兵的值来取代。

 原因2今天才发现,root会因为旋转操作而改变位置,如果我像打印二叉树那样打印最初的root,很可能只打印了一半。举例:最初的root是99,它是我随机产生的数(0~99)中最大的,它一定会是右叶子节点 。这样,我如果以最初的root打印树,只有1个节点。由于没考虑这个特性,我还一直找bug,直到调试时候,自己认真跟踪数值变化,才发现。

调试信息如下,供参考

init_rb_root: mNil =0x1956030;root =0x1956060
root is 65
************insert_node*************
i = 1 ,root=0x1956060
insert_node : befor insert : pNode->left->value = -1
insert_node : insert left:46
insert fixup
i = 2 ,root=0x1956060
insert_node : befor insert : pNode->left->value = -1
insert_node : insert left:35
insert fixup
case 1
PARENT_SIDE = LEFT
case 2
case 3
right_rotate:
i = 3 ,root=0x1956060
insert_node : befor insert : pNode->left->value = -1
insert_node : insert left:56
insert fixup
case 1
PARENT_SIDE = RIGHT
i = 4 ,root=0x1956060
insert_node : befor insert : pNode->left->value = -1
insert_node : insert left:8
insert fixup
case 1
PARENT_SIDE = LEFT
case 2
case 3
right_rotate:
i = 5 ,root=0x1956060
insert_node : befor insert : pNode->left->value = -1
insert_node : insert left:38
insert fixup
case 1
PARENT_SIDE = RIGHT
i = 6 ,root=0x1956060
************insert_node*************
get_tree_height: pRoot = 0x1956060;value = 65
get_tree_height: pRoot = 0x19561b0;value = 38
get_tree_height: pRoot = 0x1956030;value = -1
get_tree_height: pRoot = 0x1956030;value = -1
get_tree_height: pRoot = 0x1956030;value = -1
creat tree succuess!Tree heigh is:2
get_tree_height: pRoot = 0x1956060;value = 65
get_tree_height: pRoot = 0x19561b0;value = 38
get_tree_height: pRoot = 0x1956030;value = -1
get_tree_height: pRoot = 0x1956030;value = -1
get_tree_height: pRoot = 0x1956030;value = -1
print_tree: height = 2
print_tree :Nil(pRoot->parent) = 0x1956120
_______________________
breath begin,enter root:
  65B    
 __||__  
38R  ooB  
-----------
breath end!
-----------

所以,创建树的办法和二叉树不一样,因为root不是固定的。之前的代码是这样的,要更改

Tree create_tree(int num)
{
    srand(time(NULL));
    Tree root = init_rb_root(rand()%100);
    printf("root is %d\n",root->value);
    int i ;

    printf("************insert_node*************\n");
    for(i=1;i<num;i++)
    {
        printf("i = %d ,root=%p\n",i,root);
        insert_node(root,rand()%100);
    } 
    printf("************insert_node*************\n");

    printf("creat tree succuess!Tree heigh is:%d\n",get_tree_height(root));
    return root ;
}
~                                 

增加get_root函数,每次for循环,根据最初的root去找新的root。打印新的root就可以了

Tree create_tree(int num,Queue *pQueue)
{
    srand(time(NULL));
    Tree root = init_rb_root(rand()%100);
    Tree new_root = root;
    printf("root is %d\n",root->value);
    int i ;

    for(i=1;i<num;i++)
    {
    //    printf("i = %d ,root=%p\n",i,root);
    //  printf("new_root = %p\n",new_root);
        insert_node(new_root,rand()%100);
        new_root = get_root(root);
        print_tree(new_root,pQueue);
    }
   // printf("new_root->value = %d\n",new_root->value);
    printf("creat tree succuess!Tree heigh is:%d\n",get_tree_height(new_root));
    return new_root ;
}  
红黑树插入过程如下,oo是NULL节点,为了方便,我把NULL当成节点打印出来了。就是说,队列中有NULL节点,但是树里面不存在指向Nil节点的Nil节点。R是红色,B是黑色



本篇写太长了,分两篇写,下篇写删除的实现。

http://blog.csdn.net/xzongyuan/article/details/22934103


代码在把红黑树写好后,再发上来,估计要花点时间。

编辑中。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值