2013-01-10 40 views
3

我已经在C中实现了红黑树的插入部分,但是我在调​​用DISPLAY函数时没有得到任何输出。我用BST实现(RBT的某些部分)检查了函数的正确性,这很好。任何帮助表示赞赏。 /*实现红黑树根据CSLR */C中红黑树的实现

#include <stdio.h> 
#include <stdlib.h> 

struct rbtNode{ 
int key; 
char color; 
struct rbtNode *left; 
struct rbtNode *right; 
struct rbtNode *parent; 
}; 

struct rbtNode* root = NULL; 

void leftRotate(struct rbtNode *root,struct rbtNode *x){ 
struct rbtNode *y; 
y = x->right; //Set y 
x->right = y->left; // Turn y's left subtree into x's right subtree 
if(y->left != NULL){ 
    y->left->parent = x; //Bridge the y's left sublink 
} 
y->parent = x->parent; //Bridge x's old parent and y's parent 
if(x->parent == NULL){ 
    root = y; 
} 
else if(x->key == x->parent->left->key){ 
    x->parent->left = y; //Bridge x's old parent's left or right child 
} 
else x->parent->right = y; 
y->left = x; //put x on y's left 
x->parent = y; //Take care of x's parent 

return; 
} 

void rightRotate(struct rbtNode *root,struct rbtNode *y){ 
struct rbtNode *x; 
x = y->left; //set x 
y->left = x->right; //Turn x's right subtree into y's left subtree 
if (x->right != NULL){ 
    x->right->parent = y; 
} 
x->parent = y->parent; //Bridge y's old parent and x's parent 
if(y->parent == NULL){ 
    root = x; 
} 
else if(y->key == y->parent->left->key){ 
    y->parent->left = x; //Bridge y's old parent's left or right child 
} 
else y->parent->right = x; 
x->right = y; //put y on x's right 
y->parent = x; //Take care of y's parent 

return; 

} 

void rbInsertFix(struct rbtNode *root,struct rbtNode *z){ 
struct rbtNode *y; 
while (z->parent->color == 'r'){ 
    if (z->parent->key == z->parent->parent->left->key){ 
     y = z->parent->parent->right; 
     if (y->color == 'r'){ 
      z->parent->color = 'b'; 
      y->color = 'b'; 
      z->parent->parent->color = 'r'; 
      z = z->parent->parent; 
     } 
     else if (z->key == z->parent->right->key){ 
      z = z->parent; 
      leftRotate(root,z); 
     } 
     z->parent->color = 'b'; 
     z->parent->parent->color = 'r'; 
     rightRotate(root,z->parent->parent); 
    } 
    else { 
     y = z->parent->parent->left; 
     if (y->color == 'r'){ 
      z->parent->color = 'b'; 
      y->color = 'b'; 
      z->parent->parent->color = 'r'; 
      z = z->parent->parent; 
     } 
     else if (z->key == z->parent->left->key){ 
      z = z->parent; 
      rightRotate(root,z); 
     } 
     z->parent->color = 'b'; 
     z->parent->parent->color = 'r'; 
     leftRotate(root,z->parent->parent); 
    } 
} 
root->color = 'b'; 
} 

void rbInsert(struct rbtNode *root, int val){ 
struct rbtNode *z = (struct rbtNode*)malloc(sizeof(struct rbtNode)); 
z->key = val; 
z->left = NULL; 
z->right = NULL; 
z->color = 'r'; 
struct rbtNode *x = root; 
struct rbtNode *y; 
if (root == NULL){ 
    root = z; 
    root->color = 'b'; 
    return; 
} 
while (x != NULL){ 
    y = x; 
    if (z->key < x->key){ 
     x = x->left; 
    } 
    else x = x->right; 
} 
z->parent = y; 
if (y == NULL){ 
    root = z; 
} 
else if(z->key < y->key){ 
    y->left = z; 
} 
else y->right = z; 
rbInsertFix(root,z); 

return; 
} 

/*Display RBT - Inorder Traversal*/ 
void inorderTree(struct rbtNode* root){ 
struct rbtNode* temp = root; 
if (temp != NULL){ 
    inorderTree(temp->left); 
    printf(" %d-%c ",temp->key,temp->color); 
    inorderTree(temp->right); 
} 
return; 
} 

int main(int argc, char* argv[]){ 
int loop = 1; 
while(loop){ 
    printf("\nRed Black Tree Management - Enter your choice : "); 
    printf("\n1\tInsert into RBT\n2\tDisplay RBT inorder\n"); 
    int choice; 
    int val; 
    scanf("%d",&choice); 
    switch(choice){ 
     case 1: 
     printf("\nEnter the integer you want to add : "); 
     scanf("%d",&val); 
     rbInsert(root,val); 
     break; 

     case 2: 
     printf("\nInorder tree traversal left-root-right\n"); 
     inorderTree(root); 
     break; 

     default: 
     printf("\nInvalid Choice\n"); 
    } 
    printf("\nPress '0' to terminate and '1' to continue : "); 
    scanf("%d",&loop); 
} 

return 0; 
} 
+0

我不知道错误在哪里发生。如果在插入和修改相同内容时出现错误,显示可能无法正常工作。 – Krishna

回答

2

void rbInsert(struct rbtNode *root, int val)你逝去的root为指针值。在C中,你不能通过传值来更新指针。 更改

void rbInsert(struct rbtNode *root, int val) 

void rbInsert(int val) 

,它会正常工作,因为它会使用全球root

0

你什么都不显示,因为你的树将是空的。你的代码的问题是,它永远不会修改树的root(至少这是我从第一次阅读代码时注意到的问题)。

在所有函数中,您需要将指针传递给根(即双指针),以便您可以修改它。例如,你应该这样写:

void rbInsert(struct rbtNode **root, int val) 

而不是你的单指针版本。否则代码:

root = z; 
root->color = 'b'; 
return; 

修改根的本地副本,因此不影响树。