簡體   English   中英

紅黑樹刪除相關功能實現 - RBT Minimum - Segmentation Fault

[英]Red-Black Tree delete related functions implementation - RBT Minimum - Segmentation Fault

我目前正在實施紅黑樹 (RBT) function。 到目前為止,插入和搜索 function 正在正常工作。 然而,“煩人”的部分來了。 我正在嘗試實現執行刪除的 function。 在刪除、刪除修復和移植中一切正常,但是當談到“最小”function 時,我確實遇到了分段錯誤。 很可能我沒有正確寫function,你們能幫幫我嗎?

這是與此刪除部分相關的代碼:

void rotateLeft( nodo_alberoRBT** T, nodo_alberoRBT* x)
{
    nodo_alberoRBT *y  = x->figlio_destro;    
    x->figlio_destro = y->figlio_sinistro;     
    if (y->figlio_sinistro != T_Nil)
        y->figlio_sinistro->padre = x;
    y->padre = x->padre;  
    if (x->padre == T_Nil)
        *T = y;
    else if (x == x->padre->figlio_sinistro)
        x->padre->figlio_sinistro = y;
    else
        x->padre->figlio_destro = y;
    y->figlio_sinistro   = x;            
    x->padre = y;
}

void rotateRight(nodo_alberoRBT** T, nodo_alberoRBT* y)
{
    nodo_alberoRBT *x  = y->figlio_sinistro;     
    y->figlio_sinistro  = x->figlio_destro;    
    if (x->figlio_destro != T_Nil)
        x->figlio_destro->padre = y;
    x->padre = y->padre;  
    if (y->padre == T_Nil)
        *T = x;
    else if (y == y->padre->figlio_destro)
        y->padre->figlio_destro = x;
    else
        y->padre->figlio_sinistro  = x;
    x->figlio_destro  = y;         
    y->padre = x;
}

void transplantRBT(struct nodo_alberoRBT** root, struct nodo_alberoRBT* u, struct nodo_alberoRBT* v){
    if(u->padre == T_Nil){
        *root = v;
    } 
    else if(u == u->padre->figlio_sinistro){
        u->padre->figlio_sinistro = v;
    } else {
        u->padre->figlio_destro = v;
    }

    v->padre = u->padre;
}

void deleteFixupRBT(struct nodo_alberoRBT** root, struct nodo_alberoRBT* x){
    while((x != root[0]) && (x->color == BLACK)){
        if(x == x->padre->figlio_sinistro){
            struct nodo_alberoRBT* w = x->padre->figlio_destro;

            if(w->color == RED){
                w->color = BLACK; // caso 1
                x->padre->color = RED; // caso 1
                rotateLeft(root, x->padre); // caso 1
                w = x->padre->figlio_destro; // caso 1
            }

            if((w->figlio_sinistro->color == BLACK) && (w->figlio_destro->color == BLACK)){
                w->color = RED; // caso 2
                x = x->padre; // caso 2
            }
            else if(w->figlio_destro->color == BLACK){
                w->figlio_sinistro->color = BLACK; // caso 3
                w->color = RED; // caso 3
                rotateRight(root, w); // caso 3
                w = x->padre->figlio_destro; // caso 3
            } else {
                w->color = x->padre->color; // caso 4
                x->padre->color = BLACK; // caso 4
                w->figlio_destro->color = BLACK; // caso 4
                rotateLeft(root, x->padre); // caso 4
                x = root[0]; // caso 4
            }
        } else {
            struct nodo_alberoRBT* w = x->padre->figlio_sinistro;

            if(w->color == RED){
                w->color = BLACK; // caso 1
                x->padre->color = RED; // caso 1
                rotateRight(root, x->padre); // caso 1
                w = x->padre->figlio_sinistro; // caso 1
            }

            if((w->figlio_destro->color == BLACK) && (w->figlio_sinistro->color == BLACK)){
                w->color = RED; // caso 2
                x = x->padre; // caso 2
            }
            else if(w->figlio_sinistro->color == BLACK){
                w->figlio_destro->color = BLACK; // caso 3
                w->color = RED; // caso 3
                rotateLeft(root, w); // caso 3
                w = x->padre->figlio_sinistro; // caso 3
            } else{

                w->color = x->padre->color; // caso 4
                x->padre->color = BLACK; // caso 4
                w->figlio_sinistro->color = BLACK; // caso 4
                rotateRight(root, x->padre); // caso 4
                x = root[0]; // caso 4
            }
        }
    }
    x->color = BLACK;
}

// nodo minimo
struct nodo_alberoRBT* nodo_minimoRBT(struct nodo_alberoRBT* nodo){
    while(nodo->figlio_sinistro != T_Nil){
        nodo = nodo->figlio_sinistro;
    }

    return nodo;
}

struct nodo_alberoRBT* successoreRBT(struct nodo_alberoRBT* nodo){
    if(nodo != T_Nil){
        return nodo_minimoRBT(nodo->figlio_destro);
    }

    struct nodo_alberoRBT* nodo2 = nodo->padre;
    while(nodo2 != T_Nil && nodo == nodo2->figlio_destro){
        nodo = nodo2;
        nodo2 = nodo2->padre;
    }

    return nodo2;
}

void deleteRBT(struct nodo_alberoRBT** root, struct nodo_alberoRBT* z){
    struct nodo_alberoRBT* y = z;
    char y_colore_originale;
    y_colore_originale = y->color;
    struct nodo_alberoRBT* x;

    if(z->figlio_sinistro == T_Nil){
        x = z->figlio_destro;
        transplantRBT(root, z, z->figlio_destro);
    } 
    else if(z->figlio_destro == T_Nil){
        x = z->figlio_sinistro;
        transplantRBT(root, z, z->figlio_sinistro);
    }
    else {
        y = nodo_minimoRBT(z->figlio_destro);
        y_colore_originale = y->color;
        x = y->figlio_destro;
        if(y->padre == z){
            x->padre = y;
        } else {
            transplantRBT(root, y, y->figlio_destro);
            y->figlio_destro = z->figlio_destro;
            y->figlio_destro->padre = y;
        }
        transplantRBT(root, z, y);
        y->figlio_sinistro = z->figlio_sinistro;
        y->figlio_sinistro->padre = y;
        y->color = z->color;
    }

    if(y_colore_originale == BLACK){
        deleteFixupRBT(root, x);
    }

    root[0]->color = BLACK;
}

float singolo_esperimentoRBT(int max_chiavi, int max_search, int max_delete, int max_istanze){
    double t_tot = 0;
    int istanza = 0;
    int chiave, ricerca, eliminazione;
    struct nodo_alberoRBT* t_root;

    for(istanza = 1 ; istanza <= max_istanze ; istanza++){

        t_root = T_Nil;
        clock_t inizioTempo, fineTempo; //dichiaro queste due variabili di tipo clock_t (typedef)
        inizioTempo = clock(); // inizia il tempo

        for(eliminazione = 1; eliminazione <= max_delete; eliminazione++){
            deleteRBT(&t_root, newNode(rand()));
        } 

        fineTempo = clock(); // termina il tempo
        double differenzialeTempo = (double) (fineTempo - inizioTempo);  //differenza tra tempo di fine e inizio
        t_tot = t_tot + differenzialeTempo; // sommo il tempo totale dell'esperimentoBST singolo

    }

    return t_tot/max_chiavi;
}

void esperimentoRBT(int min_chiavi, int max_chiavi){
    int step = 10000;
    int istanze_massime = 5;
    int percentuale_ricerca = 60;
    int chiavi = 0; 
    int seed = 164333; // seed
    double tempoBST = 0 , tempoRBT = 0;
    for(chiavi = min_chiavi; chiavi <= max_chiavi; chiavi = chiavi + step){
        double max_search = chiavi * percentuale_ricerca/100;
        double max_delete = chiavi - max_search;
        srand(seed);
        tempoBST = singolo_esperimentoBST(chiavi, max_search, max_delete, istanze_massime); // richiamo s.esperimento BST
        tempoRBT = singolo_esperimentoRBT(chiavi, max_search, max_delete, istanze_massime); // richiamo s.esperimento RBT
        printf("Tempo RBT: %f - Chiavi: %d\n",tempoRBT, chiavi);

        seed++;
    }
}

int main(void)
{
    int min_chiavi = 10000;
    int max_chiavi = 100000;

    esperimentoRBT(min_chiavi, max_chiavi);
    return 0;
}

提前致謝!

這些行幾乎肯定是錯誤的:

if((w->figlio_destro->color == BLACK) && (w->figlio_sinistro->color == BLACK))

因為如果將 x 作為節點刪除並且它是葉節點,則 w(其兄弟)將存在,但 w 的子節點可能不存在。 這意味着 w->figlio_destro 可能是 NULL 和 w->figlio_sinistro 可能是 NULL

你應該有一個 function (可能是內聯的)

bool IsBlack(const nodo_alberoRBT* n) { return n == NULL || n->顏色==黑色)

並使用它。

插入案例也是如此。 底部插入節點的Parent節點的Uncle,可能不存在

黑節點:如果葉子存在則可能不存在,否則它確實存在紅節點:總是真實的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM