哪位大牛帮我debug一个二叉树的程序,急啊,谢谢!

xjfox 2006-10-19 10:41:58
#include <stdio.h>
#include <malloc.h>

typedef struct treeNode
{
int key;
struct treeNode *Lchild;
struct treeNode *Rchild;
}treeNodeType;

treeNodeType *searchNode(treeNodeType *bn, int key)
{
if(bn == NULL)
return bn;
while(bn->key != key)
{
if(key < bn->key)
bn = bn->Lchild;
else
bn = bn->Rchild;
if(bn == NULL)
break;
}
return bn;
}

treeNodeType *insertNode(treeNodeType *bn, treeNodeType *cn, int key)
{
if(cn == NULL)
{
treeNodeType *cn = (treeNodeType *)malloc(sizeof(treeNodeType));
cn->Lchild = NULL;
cn->Rchild = NULL;
cn->key = key;
if(bn == NULL)
return cn;
if(key < bn->key)
bn->Lchild = cn;
else
bn->Rchild = cn;
}

if(key < cn->key)
insertNode(cn, cn->Lchild, key);
else if(key > cn->key)
insertNode(cn, cn->Rchild, key);
return bn;
}

void leverOrderPrintTree(treeNodeType *bn)
{
treeNodeType *queue[100];
int front, rear;
if(!bn)
return;
front = -1;
rear = 0;
queue[rear] = bn;

while(front != rear)
{
front++;
printf("%d ", queue[front]->key);

if(queue[front]->Lchild)
{
rear++;
queue[rear] = queue[front]->Lchild;
}

if(queue[front]->Rchild)
{
rear++;
queue[rear] = queue[front]->Rchild;
}
}
}

void main()
{
treeNodeType *bn;
int key;
bn = NULL;
while(1)
{
printf("Insert the key:\n");
scanf("%d", &key);
if(key == -1)
break;
bn = insertNode(bn, bn, key);
}

printf("Display the tree after insert:\n");
leverOrderPrintTree(bn);
}

当我输入第二个数时,在函数insertNode的
if(key < cn->key)
insertNode(cn, cn->Lchild, key);
else if(key > cn->key)
insertNode(cn, cn->Rchild, key);
会出错,而且错误不可见!
...全文
322 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
xjfox 2006-10-20
  • 打赏
  • 举报
回复
谢谢你们,我学到了很多东西!
mu_yang 2006-10-20
  • 打赏
  • 举报
回复
良C与劣C~呵呵
-------------------------
勿以善小而不为
勿以恶小而为之
是我的信条
有些"高手"对此很不屑
他们因为觉得没有"深度"而不以为然
他们喜欢通过放纵自己的为标准所容许的
但决不是标准所提倡的恶劣习惯
在代码中埋伏下种种隐患
最后再通过"巨大"的努力去改正
估计这样会很有成就感
xjfox 2006-10-20
  • 打赏
  • 举报
回复
知道了!谢谢!!
Jokar 2006-10-20
  • 打赏
  • 举报
回复
我能够给别人的分是不是会越来越少?
----------------------------
每天上csdn~ 回自动 加 10分~ 还有多回答问题~ 这样知识的理解 也会不断加深~
xjfox 2006-10-20
  • 打赏
  • 举报
回复
呵呵,会给分了,发现我真是个菜鸟,无论是C还是论坛上的操作。BTW:我能够给别人的分是不是会越来越少?
Jokar 2006-10-20
  • 打赏
  • 举报
回复
平分~ 1人10分就行了` 外边 主列表 点击 管理~ 呵呵
xjfox 2006-10-20
  • 打赏
  • 举报
回复
谢谢Jokar和mu_yang的指导!我这下是完全明白啦!唉,看来我的C语言还要大大的加强啊……
BTW:怎么把分给你们啊?
Jokar 2006-10-20
  • 打赏
  • 举报
回复
良C与劣C~呵呵
mu_yang 2006-10-20
  • 打赏
  • 举报
回复
但是照说第二次之后判断时应该发现key 等于cn->key,应该不会执行才对啊,不太明白……
------------------------------------------------------------------------
我上机看了一下
发现你在nsertNode中定义了两个cn
这是问题的根本
if(cn == NULL)中的cn与if(key < cn->key)中的cn是两个
treeNodeType *cn = (treeNodeType *)malloc(sizeof(treeNodeType));
应该改成
cn = (treeNodeType *)malloc(sizeof(treeNodeType));

我觉得你的变量名取的很差(cn,bn)
乱取名甚至不顾重名是造成混乱以及调试困难的主要原因
我建议你取有意义的名字
Jokar 2006-10-20
  • 打赏
  • 举报
回复
但是照说第二次之后判断时应该发现key 等于cn->key,应该不会执行才对啊,不太明白……
--------------------
这个~ 你的代码的问题~~


treeNodeType *insertNode(treeNodeType *bn, treeNodeType *cn, int key) // 形参中有个
cn了~

而treeNodeType *cn = (treeNodeType *)malloc(sizeof(treeNodeType)); 你又定义了个cn
所以 在 if 语句之内 编译器~ 判断你要使用的是 这个 cn而不是 那个形参 cn~

但是 到了if 语句之外 你的第二个cn 的作用域就结束了~ 编译器判断 你要使用的是 形参
的cn~ 因为之前的所用操作都是对 第二个cn的 (包括分配空间和 初始化内容等等),

所以形参cn还是 NULL的~ 这样 key 等于cn->key 之说是根本不可能的~



看来 还可以这么改了~

treeNodeType *cn = (treeNodeType *)malloc(sizeof(treeNodeType));改为:
cn = (treeNodeType *)malloc(sizeof(treeNodeType)); 然后那个else 就可以不加了~

我想这才是lz你真正的 意思~

Jokar 2006-10-20
  • 打赏
  • 举报
回复
正如lz你说的~ 你可以自己单步跟踪, 看看当输入第二个节点时的第二层第归 函数的执行情况~ 可以发现 :
if(cn == NULL)
{
treeNodeType *cn = (treeNodeType *)malloc(sizeof(treeNodeType));
cn->Lchild = NULL;
cn->Rchild = NULL;
cn->key = key;
if(bn == NULL)
return cn;
if(key < bn->key)
bn->Lchild = cn;
else
bn->Rchild = cn;
}

这段执行完后`
if(key < cn->key)
insertNode(cn, cn->Lchild, key);
else if(key > cn->key)
insertNode(cn, cn->Rchild, key);
return bn;

这段由于不与之前的 if构成分支,so。。。 当然会执行了~ 这个根本就不是你的本意~呵呵:)
Jokar 2006-10-20
  • 打赏
  • 举报
回复
而会直接跳到最后一句返回啊??
-------------------------
对于第二个节点来说~
if(bn == NULL) /* 对于第二个和以后的节点来说 bn永远都不是 NULL,因为 bn是从上一层第归
* insertNode(cn, cn->Lchild/*或cn->Rchild*/, key);这句第归调用时 传进
* 来的cn, 所以: 因为没有else, if(cn == NULL) {...} 括号内的内容执行 *完之后~ 剩下的 代码不和if(cn == NULL) 构成分支,所以会继续执行下去,必然再次进入第
*归,这样 肯定会无限第归, 最后栈溢出,程序推出~
*/
return cn;
if(key < bn->key)
bn->Lchild = cn;
else
bn->Rchild = cn;
因为
mu_yang 2006-10-19
  • 打赏
  • 举报
回复
"会直接跳到最后一句返回"
--------------------------------
为什么会直接"跳"?
xjfox 2006-10-19
  • 打赏
  • 举报
回复
谢谢你!我看懂你的意思了,但是我不明白的是:根据if的判断条件,其实根本不会继续执行insertNode函数,而会直接跳到最后一句返回啊??
mu_yang 2006-10-19
  • 打赏
  • 举报
回复
第二节点
因为insertNode(cn, cn->Lchild, key);
而执行下面代码
if(cn == NULL)
{

}

因为对第二节点你没有在上面if里正确地返回而且根本没有返回
所以执行之后会继续执行下面代码

if(key < cn->key)
insertNode(cn, cn->Lchild, key);
else if(key > cn->key)
insertNode(cn, cn->Rchild, key);

如此就无限递归了
xjfox 2006-10-19
  • 打赏
  • 举报
回复
弱弱的说:其实还是不太明白。。。麻烦哪位解释清楚一点。。。
mu_yang 2006-10-19
  • 打赏
  • 举报
回复
无限递归的原因
xjfox 2006-10-19
  • 打赏
  • 举报
回复
但是照说第二次之后判断时应该发现key 等于cn->key,应该不会执行才对啊,不太明白……
xjfox 2006-10-19
  • 打赏
  • 举报
回复
真的是的!太感谢你了!回复了之后再好好看看程序!20分是你的了!
Jokar 2006-10-19
  • 打赏
  • 举报
回复
reeNodeType *insertNode(treeNodeType *bn, treeNodeType *cn, int key)
{
if(cn == NULL)
{
treeNodeType *cn = (treeNodeType *)malloc(sizeof(treeNodeType));
cn->Lchild = NULL;
cn->Rchild = NULL;
cn->key = key;
if(bn == NULL)
return cn;
if(key < bn->key)
bn->Lchild = cn;
else
bn->Rchild = cn;
}
else //加个else就OK了~ 主要是因为 第二次 之后 下边的代码会重复执行了~
if(key < cn->key)
insertNode(cn, cn->Lchild, key);
else if(key > cn->key)
insertNode(cn, cn->Rchild, key);
return bn;
}


呵呵~熄灯之前赶上了~
加载更多回复(2)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧