Удалить узел из двоичного дерева поиска в C
Я пытаюсь удалить узел из двоичного дерева поиска. Но когда я хочу проверить функцию, я получу сообщение об ошибке в "случае 3: два ребенка".
clist->name = temp->name;
Эта строка вызывает сообщение об ошибке. Это говорит: левый операнд должен быть l-значением. Я новичок в C и бинарные деревья поиска. Я не могу понять, почему эта линия не работает. Я нашел много идей в интернете, как реализовать функцию удаления. И все эти подходы используют эту строку кода.
Ниже приводится полная функция.
(moreThan, lessThan, toLowerCase - вспомогательная функция, которую я реализовал. И они работают нормально)
struct student {
int ID;
char name[20];
struct student *left;
struct student *right;
};
struct student * minValueNode(struct student* node) {
struct student* current = node;
while (current->left != NULL)
current = current->left;
return current;
}
struct student * bst_delete (struct student *clist, char* token, struct student **parent)
{
if (clist == NULL)
return clist;
char* clistName = clist->name;
char* tok = token;
toLowerCase(clistName);
toLowerCase(tok);
if (lessThan(tok, clistName))
clist->left = bst_delete(clist->left, token, &clist->left);
else if (greaterThan(tok, clistName))
clist->right = bst_delete(clist->right, token, &clist->right);
else
{
//Case 1: No children
if (clist->left == NULL && clist->right == NULL) {
free(clist);
clist = NULL;
}
//Case 2: One Child
if (clist->left == NULL) {
struct student *temp = clist;
clist = clist->right;
free(temp);
} else if (clist->right == NULL) {
struct student *temp = clist;
clist = clist->left;
free(temp);
}
//Case 3: Two Children
else {
struct student *temp = minValueNode(clist->right);
clist->name = temp->name;
clist->right = bst_delete(clist->right, temp->right, &clist->right);
}
}
return clist;
}
Было бы здорово, если бы кто-нибудь мог сказать мне, почему эта линия не работает. И как я мог исправить эту ошибку.
Благодарю вас!
1 ответ
Вы не можете скопировать массив в c посредством прямого присваивания, что вы действительно хотите сделать, это скопировать элементы массива - для этого вы можете использовать strcpy -
strcpy(clist->name, temp->name);
или так как размер постоянен, используйте немного более безопасный -
strncpy(clist->name, temp->name, 20);
На самом деле вам здесь повезло, вы могли бы использовать указатели для строк имен (выделять их динамически), что сделало бы это назначение допустимым кодом (хотя все равно не копировало бы содержимое строки так, как вам хотелось бы, просто перекрывая один указатель другим) и разрешить компиляцию кода, но тогда это привело бы к утечкам памяти и совместному использованию указателей между узлами - это было бы намного сложнее отлаживать.
В этом случае правое значение в присваивании может уменьшиться до указателя, но левое значение не может (так как этот массив статически размещен внутри структуры), поэтому компилятор жалуется на l-значение.