- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我实现了一个删除树节点及其子树的函数,如下所示:
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,供大家引用。
二叉树.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__
二叉树.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);
}
非常感谢。
最佳答案
free不会将传递的指针设置为 NULL
。
删除调用后调用 PreorderTraverse
Undefined Behavior 因为该函数将尝试取消引用已释放的动态内存。
关于C 删除二叉树后死循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42338697/
我的 php/mysql 脚本有问题。它应该只输出 while 循环一次,但我得到了无限循环和无休止的页面。 $query = mysql_query("SELECT * FROM users WHE
我又来了!所以,我正在用 C++ 开发一个 GBC 模拟器,但我遇到了一些问题。首先,我在 VS10 中使用 Qt,到目前为止它运行良好。但是,我有我的 GUI(主窗口)和一些对象(QListWidg
所以这是我正在做的同一个拖放游戏项目,但是我遇到了一个无限循环问题,我想在其中使用 while(backpackLength 0) { document.getElem
我已经花了 3 个小时试图让这段代码工作,但是每当我尝试时我都会陷入循环并且控制台不断循环。我已经尝试了所有方法 - 我创建了一个只返回 i 并重新分配值的函数,但它似乎不起作用。 出于某种原因,每当
我使用 lua 接口(interface)在我的 C# 程序中获得 lua 支持,如果用户提交这样的代码,工作线程将卡住 while true do end 我有一种方法可以检测无限循环是否正在运行,
这个问题在这里已经有了答案: How does a for loop work, specifically for(;;)? (6 个答案) 关闭 7 年前。 虽然我有一些 Java 经验,但下面的
我有问题。我需要让一个程序在后台运行。该程序用于收集数据并将其保存在我的数据库中。 我开始这样做了: func main() { for { doAll() } } 一次从所有
当我在 Internet Explorer 10 中查看代码时,我收到以下错误(它不一定以标准模式呈现,由于页面的服务方式,这超出了我的控制范围)。 http://errors.angularjs.o
我在 servlet 中遇到了一些问题,每次我更改下拉菜单中的选项时,一个不同的值将传递给 servlet,然后它会导致无限循环。当我没有更改下拉列表中的选项(值没有变化)时,没有错误。 这是我的代码
iOS8 中引入了可自动调整大小的表格 View 单元格(WWDC Session 226 What's new in table and collection views)。在我的项目中,我正在尝试
我是一名优秀的程序员,十分优秀!