Основные проблемы
Как уже говорилось, строка 53
иначе, если (par = par-> parent-> left)
должно быть
else if(par == par->parent->left)
Алгоритм в insertFixup не является правильным, например, для вставки данных 3, затем 2, а затем 1 производит cra sh, я вижу идентичное определение для inte rnet, возможно, вы его получили, но, к сожалению, ваш источник содержит ошибки Это определение работает:
void insertFixup(node **root, node *new) {
while (new != *root && new->parent->color == 'R') {
if (new->parent == new->parent->parent->left) {
if (new->parent->parent->right && new->parent->parent->right->color == 'R') {
new->parent->color = 'B';
new->parent->parent->right->color = 'B';
new->parent->parent->color = 'R';
new = new->parent->parent;
}
else {
if (new == new->parent->right) {
new = new->parent;
left_rotate(root, new);
}
new->parent->color = 'B';
new->parent->parent->color = 'R';
right_rotate(root, new->parent->parent);
}
}
else {
if (new->parent->parent->left && new->parent->parent->left->color == 'R') {
new->parent->color = 'B';
new->parent->parent->left->color = 'B';
new->parent->parent->color = 'R';
new = new->parent->parent;
}
else {
if (new == new->parent->left) {
new = new->parent;
right_rotate(root, new);
}
new->parent->color = 'B';
new->parent->parent->color = 'R';
left_rotate(root, new->parent->parent);
}
}
}
(*root)->color = 'B';
}
Дополнительные проблемы
Неверная подпись * main *, main возвращает int
Если пользователь не вводит int , ваша scanf строка 160 не устанавливает men , и вы можете проверить никогда не инициализированное значение , Всегда проверьте возвращаемое значение scanf , например, чтобы быть совместимым с кодом после:
if (scanf("%d", &men) != 1)
men = -1;
In
while ((c = fgetc(stdin)) != '\n') {}
c установлено, но никогда не используется, и наихудшее, если вы достигнете, например, EOF , потому что ввод был перенаправлен в файл, вы будете l oop без окончания , Например,
while ((c = fgetc(stdin)) != '\n')
if (c == EOF)
exit(0);
Строка 10:
int count = 0;
определить глобальную переменную, которая никогда не использовалась, вы можете удалить эту строку
Чтобы проверить мое предложение, я добавил эту функцию для отображения дерева:
void display(node * x){
if (x) {
display(x->left);
printf("%d ", x->info);
display(x->right);
}
}
, и я изменил ваш main , чтобы иметь возможность отображать дерево:
int main()
{
int men, c, data;
node *root = NULL;
while (1) {
fputs("\n"
"1.) Insert\n"
"2.) exit\n"
"3.) Display tree\n"
"Enter your choice : ",
stdout);
if (scanf("%d", &men) != 1)
men = -1;
switch (men) {
case 1:
printf("Enter data : ");
scanf("%d", &data);
insert(&root, data);
printf("%d successfully added!", data);
break;
case 2:
exit(0);
case 3:
display(root);
putchar('\n');
break;
default:
puts("Invalid choice!");
while ((c = fgetc(stdin)) != '\n')
if (c == EOF)
exit(0);
break;
}
}
}
Компиляция и исполнение:
bruno@bruno-XPS-8300:/tmp/t$ gcc -Wall -Wextra t.c
bruno@bruno-XPS-8300:/tmp/t$ ./a.out
1.) Insert
2.) exit
3.) Display tree
Enter your choice : 1
Enter data : 3
3 successfully added!
1.) Insert
2.) exit
3.) Display tree
Enter your choice : 1
Enter data : 2
2 successfully added!
1.) Insert
2.) exit
3.) Display tree
Enter your choice : 1
Enter data : 1
1 successfully added!
1.) Insert
2.) exit
3.) Display tree
Enter your choice : 3
1 2 3
1.) Insert
2.) exit
3.) Display tree
Enter your choice : 1
Enter data : 5
5 successfully added!
1.) Insert
2.) exit
3.) Display tree
Enter your choice : 1
Enter data : 4
4 successfully added!
1.) Insert
2.) exit
3.) Display tree
Enter your choice : 3
1 2 3 4 5
1.) Insert
2.) exit
3.) Display tree
Enter your choice : 2
bruno@bruno-XPS-8300:/tmp/t$