C中的红黑树删除故障

Posted

技术标签:

【中文标题】C中的红黑树删除故障【英文标题】:Red Black Tree delete malfunction in C 【发布时间】:2012-02-05 08:52:23 【问题描述】:

我几乎完成了一棵红黑树,但我的删除出现故障。它可能会删除一个它可能不会删除的节点。在我删除根目录并按下打印选项后,我的屏幕上充斥着我在树中已有的节点。在2,1,7,5,8,11,14,15,4 的测试树中,如果我删除root=7 并按顺序打印,我会得到2,4,5,8,1,2,4,5,8,1,.....,依此类推,直到程序崩溃。如果我删除 2,程序会立即崩溃。节点 11 像 1-4-15 一样删除所有叶子。我试图通过调试找到问题,但一切似乎都正常。该代码基于 Cormen 对算法的介绍。谢谢!

void RB_delete(struct node* z,struct node* y) //delete z y=z on call

    struct node *x;
    enum type originalcolor;         //x  moves into y's original position
    originalcolor=y->color;     // Keep track of original color

        if (z->LC==nill)        //case 1: (z has no LC)
        
            x=z->RC;
            RB_transplant(z,z->RC); 
        else if (z->RC==nill)           //case 2: z has LC but no RC
        
            x=z->LC;
            RB_transplant(z,z->LC);
        
        else            // two cases: z has both Children
        
            y=tree_minimum(z->RC);      //find  successor
            originalcolor=y->color;     //save color of successor
            x=y->RC;
                if (y->P==z)    //successor has no LC cause its nill
                    x->P=y;
                else
                
                    RB_transplant(y,y->RC);
                    y->RC=z->RC;
                    y->RC->P=y;
                
            RB_transplant(z,y);
            y->LC=z->LC;
            y->LC->P=y;
            y->color=z->color;
        
        if (originalcolor == black)
            RB_delete_fix(x);
        free(z);


void io_print(struct node *aux,struct node *auxnill)

    HANDLE  hConsole;
    hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    if(aux != auxnill)
    
        io_print(aux->LC,auxnill);
        if (aux->color==red)
        
            SetConsoleTextAttribute(hConsole, 12);
            printf("%d,\n",aux->key);fflush(stdout);
            SetConsoleTextAttribute(hConsole, 15);
        
        if (aux->color==black)
        
            SetConsoleTextAttribute(hConsole, 9);
            printf("%d,\n",aux->key);fflush(stdout);
            SetConsoleTextAttribute(hConsole, 15);
        
            io_print(aux->RC,auxnill);
    

【问题讨论】:

所以你的意思是调试的时候不会崩溃? nill 应为 nil。它代表拉丁语nil(“无”),不在列表中。 当我删除 7 时,它在调试中删除得很好,但是当我使用 print 时,我得到 root:8 in order RB tree:1,2,4,5,8,1,2,4,5,8,1,2,4,5,8,...... 到无穷大... nill 是一个哨兵。它是一个替换 null 的结构。我认为有些指针是错误的,但我找不到它们...... 我明白你用 nill 做什么。但是这样的哨兵通常被称为“nil”,只是说。 ;) 【参考方案1】:

嗯,移植中有一个错误的指针……我找不到它,因为我没有太注意。我有:

void RB_transplant(struct node *aux,struct node *auxchild)  //replace the subtree rooted at node aux with the subtree rooted at aux-LC or aux->RC

    if (aux->P==nill)                           //if aux=root child becomes root
        root=auxchild;
    else if (aux==aux->P->LC)               //if child is a LC
        aux->P->LC=auxchild;                
    else aux->P->RC=auxchild;                   //if child is RC //connect grandparent's->RC with child
        auxchild->P=aux->P;                         //connect child to point to parent

问题出在第 5 行,其中 aux 是=>auxhild... 问题已解决 :)

【讨论】:

以上是关于C中的红黑树删除故障的主要内容,如果未能解决你的问题,请参考以下文章

Sedgewick的红黑树

红黑树删除操作

史上最清晰的红黑树讲解(上)

史上最清晰的红黑树讲解(下)

最容易懂的红黑树

爱恨交织的红黑树