我实现了一个删除树节点及其子树的函数,如下所示:
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);
}
这里,参数" action"是一个函数指针,它将节点的数据作为参数并具有void返回类型,用于调用另一个打印节点数据的函数。
这是我的主要内容:
#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);
}
非常感谢。
答案 0 :(得分:3)
free未设置指向NULL
的指针。
删除后调用PreorderTraverse
调用Undefined Behavior ,因为该函数将尝试取消引用释放的动态内存。
答案 1 :(得分:0)
BinaryTree.c上的第38行(函数MakeRightSubTree
)应为
free(main->right);
而不是
(main->right);