[英]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.