Удаление дерева - C (СИ)
Формулировка задачи:
НЕ работает удаление дерева. Программа вызывает срабатывание точки остановы.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
struct tree{
int inf;
struct tree *L;
struct tree *R;
};
void createTree(struct tree *N)
{
struct tree *T;
int x;
printf("Введите левого сына для %d, если левого сына нет, то введите любой символ, не являющийся числом.\n",N->inf);
fflush(stdin);
if (scanf("%d", &x) != 0)
{
T = (struct tree*)malloc(sizeof (struct tree*));
T->L = NULL;
T->R = NULL;
T->inf = x;
N->L = T;
createTree(T);
}
printf("Введите правого сына для %d, если левого сына нет, то введите любой символ, не являющийся числом.\n",N->inf);
fflush(stdin);
if (scanf("%d", &x) != 0)
{
T = (struct tree*)malloc(sizeof (struct tree*));
T->L = NULL;
T->R = NULL;
T->inf = x;
N->R = T;
createTree(T);
}
return;
}
void pObhod(struct tree *N)
{
printf("%d ", N->inf);
if(N->L) pObhod(N->L);
if(N->R) pObhod(N->R);
}
void delete(struct tree *N)
{
struct tree *x=NULL, *y=NULL;
if (N->R)
x = N->R;
if (N->L)
y = N->L;
free (N);
if (x)
delete(x);
if (y)
delete(y);
}
int main()
{
struct tree *Root, *N;
int a;
setlocale(0,"");
printf("Введите корень (число) -> ");
if (scanf("%d", &a) == 0)
{
printf("Некорректный корень.\n");
return 0;
}
Root = (struct tree*)malloc(sizeof(struct tree*));
Root->inf = a;
Root->L = NULL;
Root->R = NULL;
createTree(Root);
printf("Прямой обход промежуточного дерева -> ");
pObhod(Root);
printf("\n");
delete(Root);
printf("\n");
return 0;
}Решение задачи: «Удаление дерева»
textual
Листинг программы
void delete(struct tree *N)
{
if (N == NULL) return; /*вылазим из рекурсии*/
delete(N->L);/*левое удаляем*/
delete(N->R);/*правое удаляем*/
free(N); /*удаляем себя*/
}
Объяснение кода листинга программы
- Входной параметр функции -
N, это указатель на узел дерева. - Если
NравенNULL, то функция сразу возвращает управление. - Рекурсивный вызов функции
deleteдля левого поддерева, передавая в качестве аргументаN->L. - Рекурсивный вызов функции
deleteдля правого поддерева, передавая в качестве аргументаN->R. - Вызов функции
freeдля освобождения памяти, выделенной под узелN. Nсодержит указатель на левое поддерево (L), и на правое поддерево (R).- В случае, если
Nявляется листом (у него отсутствуют и левое, и правое поддеревья), то после вызова функцииfreeдляN, управление возвращается в точку вызова функцииdelete. - Если узел
Nимеет и левое, и правое поддеревья, то после вызова рекурсивных функцийdeleteдля левого и правого поддеревьев, управление возвращается в точку вызова функцииdelete. - Если узел
Nимеет только левое поддерево, то после вызова рекурсивной функцииdeleteдля левого поддерева, управление возвращается в точку вызова функцииdelete. - Если узел
Nимеет только правое поддерево, то после вызова рекурсивной функцииdeleteдля правого поддерева, управление возвращается в точку вызова функцииdelete. - После вызова функции
freeдляN, указательNстановится недействительным. - При каждом вызове рекурсивной функции
deleteдля левого или правого поддерева, соответствующее поддерево удаляется, и управление возвращается в точку вызова функцииdelete. - Если узел
Nимеет и левое, и правое поддеревья, то порядок их удаления не важен. - Если узел
Nимеет только левое поддерево, то после удаления левого поддерева, управление возвращается в точку вызова функцииdelete. - Если узел
Nимеет только правое поддерево, то после удаления правого поддерева, управление возвращается в точку вызова функцииdelete. - Функция
deleteвызывает функциюfreeдля каждого узла дерева, начиная с корня и до листьев. - Функция
freeосвобождает память, выделенную под каждый узел дерева, начиная с корня и до листьев. - В случае, если дерево имеет только один узел (корень), то после вызова функции
freeдля этого узла, управление возвращается в точку вызова функцииdelete. - Если дерево пустое, то после вызова функции
freeдляN, управление возвращается в точку вызова функцииdelete. - Если дерево не пустое, то после удаления всех узлов дерева, управление возвращается в точку вызова функции
delete.