Я реализовал функцию, которая удаляет узел дерева вместе с его поддеревьев, как это:C Бесконечный цикл после удаления двоичного дерева
void DeleteTree(BTreeNode * bt){
if(bt == NULL)
return;
DeleteTree(bt->left);
DeleteTree(bt->right);
printf("del tree data: %d \n", bt->data);
free(bt);
}
А то у меня есть еще одна функция, которая просматривает дерево:
void PreorderTraverse(BTreeNode * bt, VisitFuncPtr action){
if(bt == NULL)
return;
action(bt->data);
PreorderTraverse(bt->left, action);
PreorderTraverse(bt->right, action);
}
Здесь параметр «действие» является указателем на функцию, который принимает данные узла как аргумент и имеет тип возвращаемого типа, используемый для вызова другой функции, которая печатает данные, которые имеет узел.
Вот моя главная:
#include <stdio.h>
#include <stdlib.h>
#include "BinaryTree.h"
void ShowIntData(int data){
printf("%d ", data);
}
int main(){
BTreeNode * bt1 = MakeBTreeNode();
BTreeNode * bt2 = MakeBTreeNode();
BTreeNode * bt3 = MakeBTreeNode();
BTreeNode * bt4 = MakeBTreeNode();
BTreeNode * bt5 = MakeBTreeNode();
BTreeNode * bt6 = MakeBTreeNode();
SetData(bt1, 1);
SetData(bt2, 2);
SetData(bt3, 3);
SetData(bt4, 4);
SetData(bt5, 5);
SetData(bt6, 6);
MakeLeftSubTree(bt1, bt2);
MakeRightSubTree(bt1, bt3);
MakeLeftSubTree(bt2, bt4);
MakeRightSubTree(bt2, bt5);
MakeRightSubTree(bt3, bt6);
PreorderTraverse(bt1, ShowIntData);
printf("\n");
DeleteTree(bt3);
PreorderTraverse(bt1, ShowIntData);
return 0;
}
Проблема заключается в том, после того, как DeleteTree, когда PreorderTraverse вызывается снова, программа попадает в бесконечный цикл, печатая некоторые значения для мусора. Не могли бы вы объяснить, почему это происходит? Для вашей справки, я покажу вам BinaryTree.h и BinaryTree.c ниже для вашей справки.
BinaryTree.h
#ifndef __BINARY_TREE_H__
#define __BINARY_TREE_H__
typedef int BTData;
typedef struct _bTreeNode{
BTData data;
struct _bTreeNode * left;
struct _bTreeNode * right;
} BTreeNode;
BTreeNode * MakeBTreeNode(void);
BTData GetData(BTreeNode * bt);
void SetData(BTreeNode * bt, BTData data);
BTreeNode * GetLeftSubTree(BTreeNode * bt);
BTreeNode * GetRightSubTree(BTreeNode * bt);
void MakeLeftSubTree(BTreeNode * main, BTreeNode * sub);
void MakeRightSubTree(BTreeNode * main, BTreeNode * sub);
typedef void VisitFuncPtr(BTData data);
void PreorderTraverse(BTreeNode * bt, VisitFuncPtr action);
void InorderTraverse(BTreeNode * bt, VisitFuncPtr action);
void PostorderTraverse(BTreeNode * bt, VisitFuncPtr action);
void DeleteTree(BTreeNode * bt);
#endif // __BINARY_TREE_H__
BinaryTree.c
#include <stdio.h>
#include <stdlib.h>
#include "BinaryTree.h"
BTreeNode * MakeBTreeNode(void){
BTreeNode * nd = (BTreeNode*)malloc(sizeof(BTreeNode));
nd->left = NULL;
nd->right = NULL;
return nd;
}
BTData GetData(BTreeNode * bt){
return bt->data;
}
void SetData(BTreeNode * bt, BTData data){
bt->data = data;
}
BTreeNode * GetLeftSubTree(BTreeNode * bt){
return bt->left;
}
BTreeNode * GetRightSubTree(BTreeNode * bt){
return bt->right;
}
void MakeLeftSubTree(BTreeNode * main, BTreeNode * sub){
if(main->left != NULL)
free(main->left);
main->left = sub;
}
void MakeRightSubTree(BTreeNode * main, BTreeNode * sub){
if(main->right != NULL)
(main->right);
main->right = sub;
}
void PreorderTraverse(BTreeNode * bt, VisitFuncPtr action){
if(bt == NULL)
return;
action(bt->data);
PreorderTraverse(bt->left, action);
PreorderTraverse(bt->right, action);
}
void DeleteTree(BTreeNode * bt){
if(bt == NULL)
return;
DeleteTree(bt->left);
DeleteTree(bt->right);
printf("del tree data: %d \n", bt->data);
free(bt);
}
Большое спасибо.
Время, чтобы узнать, как использовать отладчик .... – LPs
Я использовал отладчик, и он говорит, что ошибка происходит в функции ShowIntData, но если память для узла дерева освобождена, не следует, чтобы параметр bt в PreorderTraverse был равен NULL и ушел из f соборование? – Ned
См. Мой ответ. free не устанавливает переданный указатель на «NULL» автоматически. Вы должны увидеть его с помощью отладчика. – LPs