我正在尝试用C编写一个红黑树算法的实现,但在执行函数insert()之后,我遇到了崩溃,程序停止工作。该函数首先找到一个应该添加新值的位置,然后执行另一个名为Correct_Tree的函数,该函数负责纠正具有正确顺序和颜色的节点。
我收到的警告很少,但不知道如何修复它们,其他以相同方式构建的功能也能正常工作。
|69|warning: conflicting types for 'correct_tree' [enabled by default]|
|40|note: previous implicit declaration of 'correct_tree' was here|
相同的警告指向函数Rot_L
,我不知道这个警告是否会导致我的崩溃。我会感谢每一个答案,如果您需要更多信息,请告诉我。对不起我的英语,我不是母语人士。
以下是这些功能:http://ideone.com/hsYyES 和结构看起来像这样:
struct node {
int value;
int key_amounts;
char color;
struct node *parent;
struct node *left;
struct node *right;
} *root;
int insert(int n, struct node *start) {
//if node doesnt exist then add it to the tree otherwise increase amount of keys
//if tree is empty add root
if (root == NULL) {
root = (struct node*)malloc(sizeof *root);
root->value = n;
root->keys_amount = 0;
root->left = NULL;
root->right = NULL;
root->up = NULL;
} else
if (search(root, n) != NULL) {
struct node *tmp = search(root, n);
tmp->keys_amount += 1;
return 0;
} else
//if value is lower than root val then go to left son
if (n < start->value) {
//if left son exist then apply function insert for it
if (start->left != NULL) {
insert(n, start->left);
} else {
//if it doesnt exist then create
struct node *new = (struct node*)malloc(sizeof *root);
new->value = n;
new->keys_amount = 0;
new->left = NULL;
new->right = NULL;
new->up = start;
start->left = new;
correct_tree(new);
}
} else {
//if new value is higher than root
//if right son exist then apply function for it
if (start->right != NULL) {
insert(n, start->right);
} else {
//if it doesnt exist create new one
struct node *new = (struct node*)malloc(sizeof *root);
new->value = n;
new->keys_amount = 0;
new->left = NULL;
new->right = NULL;
new->up = start;
start->right = new;
correct_tree(new);
}
}
return 0;
}
//////////////////////////////////////////////////////////////////
void correct_tree(struct node *start) {
struct node *tmp = (struct node*)malloc(sizeof *root);
start->color = 'R';
while ((start != root) && (start->up->color == 'R')) {
if (start->up == start->up->up->left) {
tmp = start->up->up->right; //uncle of start for tmp
if (tmp->color == 'R') { //case 1
start->up->color = 'B';
tmp->color = 'B';
start->up->up->color='R';
start = start->up->up;
continue;
}
if (start == start->up->right) { //case 2
start = start->up;
rot_L(start);
}
start->up->color = 'B'; //case3
start->up->up->color = 'R';
rot_R(start->up->up);
break;
} else { //mirror cases
tmp = start->up->up->left;
if (tmp->color == 'R') { //case 1
start->up->color = 'B';
tmp->color = 'B';
start->up->up->color = 'R';
start = start->up->up;
continue;
}
if (start == start->up->left) { //case 2
start = start->up;
rot_R(start);
}
start->up->color = 'B'; //case3
start->up->up->color = 'R';
rot_L(start->up->up);
break;
}
}
root->color = 'B';
}
//////////////////////////////////////////////////////////////
void rot_L(struct node *start) {
struct node *tmp = (struct node*)malloc(sizeof *root);
struct node *tmp2 = (struct node*)malloc(sizeof *root);
tmp = start->right;
if (tmp != NULL) {
tmp2 = start->up;
start->right = tmp->left;
if (start->right != NULL)
start->right->up = start;
tmp->left = start;
tmp->up = tmp2;
start->up = tmp;
if (tmp2 != NULL) {
if (tmp2->left == start)
tmp2->left = tmp;
else
tmp2->right = tmp;
} else
root = tmp;
}
}
答案 0 :(得分:0)
编译器发出的警告告诉您在调用之前没有声明或定义correct_node
。编译器从调用中推断出的原型是int correct_tree(struct node *start);
,这与它稍后遇到的实际定义不兼容:void correct_tree(struct node *start)
。 rot_L()
的问题相同。在调用它们之前声明所有函数。
函数correct_node
必然会失败,因为您取消引用up
链接,而不先检查它们是否为NULL
。例如,当您第一次致电correct_node on the
左or
右child of the
root`节点时,您有:
start->color = 'R';
while ((start != root) && (start->up->color == 'R')) {
if (start->up == start->up->up->left) {
您没有初始化color
分配的root
节点的malloc()
。 root->color
可能等于'R'
的可能性很小,这会导致start->up->up->left
具有未定义的行为,start->up->up
为NULL
。
另一个问题是:
struct node *tmp = (struct node*)malloc(sizeof *root);
从不使用为tmp
分配的对象,从不释放,并且在循环中覆盖tmp
。这是一个明显的内存泄漏案例。
在rot_L
tmp
和tmp2
中,同样的问题出现了两次。