每当一个新节点被插入时,它不是分支并将NewNode指向具有最大值的分支,而是将高度为2的相同节点替换为NewNode。
问题出现在第85行。
输出量:
Enter the data of first node: 10
Enter the data of node: 7
7
L
10
Do you want to continue: 1
Enter the data of node: 6
6
L
10
Do you want to continue: 1
Enter the data of node: 11
11
R
10
Do you want to continue: 0
相反,它应该以这种方式工作:
head node=10
first node=7
L
temp=10
second node=6
L
L
temp=7
Third node=11
R
Temp=10
这意味着所有的变化都发生在头部的左和右节点,而不是像它应该的那样分支出来。
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *left;
struct node *right;
}*head;
void createtrees();
void treversetrees();
void addvalue(struct node *temp,struct node *NewNode);
void searchtree(int S,struct node *temp);
void main()
{
int S;
createtrees();
printf("\nData in Trees is\n");
//treversetrees();
printf("Enter the integer to search for: ");
scanf("%d",&S);
struct node *temp;
temp=head;
searchtree(S,temp);
}
void createtrees()
{
struct node *NewNode,*temp;
int data,answer=1;
head=(struct node*)malloc(sizeof(struct node));
if (head==NULL)
{
printf("Unable to allocate memory.");
exit(0);
}
printf("Enter the data of first node: ");
scanf("%d",&data);
head->data=data;
do
{
NewNode=(struct node*)malloc(sizeof(struct node));
if (NewNode==NULL)
{
printf("Unable to allocate memory.");\
break;
}
printf("Enter the data of node: ");
scanf("%d",&data);
printf("\n1. %d\n",data);
NewNode->data=data;
temp=head;
// printf("2\n");
if (data<temp->data)
{
// printf("3.01\n");
addvalue(temp,NewNode);
// printf("3.1\n");
}
else
{
// printf("3.02\n");
addvalue(temp,NewNode);
// printf("3.2\n");
}
printf("Do you want to continue: ");
scanf("%d",&answer);
}
while(answer==1);
}
void addvalue(struct node *temp,struct node *NewNode)
{
// printf("4\n");
if (temp==NULL)
{
temp=NewNode;
}
else if (NewNode->data<temp->data)
{
printf("L\n");
printf("\n%d\n",temp->data);
addvalue(temp->left,NewNode);
}
else
{
printf("R\n");
printf("\n%d\n",temp->data);
addvalue(temp->right,NewNode);
}
}
void searchtree(int S,struct node *temp)
{
if (temp->data==S)
{
printf("%d is found in tree",S);
return;
}
else if(temp->data>S)
{
temp=temp->right;
searchtree(S,temp);
}
else if(temp->data<S)
{
temp=temp->left;
searchtree(S,temp);
}
else if(temp==NULL)
{
printf("%d is not found in tree",S);
}
}
3条答案
按热度按时间iqxoj9l91#
这里有几个函数可以让你开始:
您应该能够自己解决其余的问题,但不需要为第一个节点做任何特殊的事情。只需将
head
初始化为NULL
,并为每个节点调用NewNode = createnode(data);
和addvalue(&head, NewNode);
。在
searchtree()
中有一个空指针解引用错误,但是你可以通过改变测试的顺序来修复它。ars1skjm2#
对于学习C语言的人来说,你已经做出了很大的努力。然而,在你最近发布的代码中有一些小问题,在另一个“答案”的评论中显示的链接。
1.未验证动态内存分配(
malloc()
)是否成功。1.代码重复(根节点没有什么特别的。)
searchtree()
* 在检查其值是否为NULL之前使用 * 节点指针。if(Node->data>data)
搜索树的错误边。1.程序退出而不释放分配的内存(被认为是内存泄漏)。
1.不检查
scanf()
的返回值。我已经“重新工作”了你最近的代码,使它的功能,因为我认为你希望它的功能。
虽然程序生成自己的数据来测试功能是很好的,但当测试没有完全测试功能时,这就不好了。
通过从
stdin
加载数据,可以轻松地创建一组或多组测试数据,用于评估程序的正确性。用于测试下面代码的数据包含在一个文件中,并且很容易运行:./a.out < test1.txt
执行结果:
数据的第一行列出了要插入到存储中的值。随后的行表示要搜索的各个值。
在开发代码时,可以简单地运行程序并输入测试数据来执行任何修改。
代码,带有一些注解:
这段代码使用了一些你需要知道的库函数。最好花时间学习什么是可用的,而不是与问题搏斗,试图重新发明它们。一旦您真正熟练了,尝试实现各种库函数的您自己的版本可能是一种娱乐。
关于测试:最后,您可能希望添加
delete( int val )
以从存储中删除节点。将文件中的“测试数据”扩展为,例如:测试意味着测试...
最后,作为练习,将操作树节点的函数移到一个单独的源文件中(将头文件
#include
中的函数原型适当地发布到main.c
和tree.c
中)。然后,考虑用一个简单的数组来替换BST实现,该数组可以动态调整大小并按排序顺序维护。main.c
,header.h
和包含测试数据的各种文件不需要修改!增编:
一旦你让一切正常工作,并决定你的树应该存储重复的数据值,这里有另一个挑战:修改代码,以便使用存储在节点中的“示例计数器”(而不是创建额外的节点)添加、显示(遍历)和删除任何重复项。
zd287kbt3#
从问题的代码
在许多方面,这是错误的。
返回
void
的void
函数是奇怪的动物:createtrees()
是复数名称,但只能在单个全局树上操作createtrees()
两次,它将覆盖head
全局指针并泄漏内存.**永远不要写交互式代码:**这是一个灾难的测试。如果你想在5个场景下测试20个元素,而程序仍然崩溃,请计算一下:数百个领域进入,小时的测试。没人想这样
我将向您展示一种封装所有树数据的可能方法。下面是一个包含代码和参数的完整示例。我看到了二叉树的代码-和类似的集合-用我们在这个问题上看到的方式编程,可能不是一种安全的方法,所以这个例子中的代码作为一个整体可能是有用的。或者只是忽略;)
你有没有注意到代码中甚至没有
Tree
?node
不是树,因为节点不是set
或linked list
。像这些集合这样的数据结构是一个-可能是空的-节点集,如果模型更接近于此,则更容易编码。关于示例
这只是个玩具为了说明,我们将使用此
这里有几个操作:
这些函数仅在
Tree
和数据上运行,并按预期运行。在向用户公开的函数中没有提到node
。原因是为了保护实现,这样我们就可以在不需要更改用户代码的情况下更改细节。而且用户也不能因为触碰内部指针而把事情搞砸。与原始发布的代码相比:
Trees
进行操作so_create
返回一个新的空树,并带有一个名称,以允许某种序列化。so_destroy
返回一个NULL
,可以用来使树指针在树被删除的同一行中无效。在复杂的代码中,它可以保存作业或时间,或两者兼而有之so_insert()
使用了预期的范例,将一个东西插入到一个 * 容器 * 中,这里是树。它更容易阅读main()
示例关于代码
生成测试数据
一个辅助函数,
vector_of_N()
返回一个小的int
数组进行测试:从0
到(N-1)
的所有值按随机顺序排列。也许你可以看到这种差异,并留在键盘发明数据在每个测试中的原始代码.
这些值是随机的,可以是示例中的16,也可以是某些测试中的几千。没什么区别。
这是在main和显示器的开始
创建
trees
由于
Tree
数据的封装,很容易创建任何数量的树。让我们尝试2 ;)printf
sso_create()
返回一个指向新树的简单指针,所以它们可以在一行中创建,直接放入树数组中。for
循环数据if
在一个树中插入奇数值并且在另一个树中插入偶数值。这只是一个玩具,所以我们可以看到如何强制标准和过滤数据,可以是任何东西我们穿过两棵树。但我们知道会发生什么,因为数据是以随机顺序插入的,但内容是事先知道的。这提供了一些安全性。
除了这个我没有做任何测试。
然后树被破坏,包含输入数据的向量被破坏,仅此而已
此代码的输出
备注:
0
到15
的随机顺序的数字。so_traverse()
接受可选的const char*
作为消息。方便测试。我没有实现搜索,因为它是微不足道的。请让我知道如果它是必要的。
完整代码
我不会评论的功能,我相信他们是非常简单的,我只是试图展示一种方法来写这一点。无论如何,请写任何问题,我会写回代码和职位。
我不会说这是一个好的解决方案,甚至是一个解决方案。但它成功了--嗯,就像这样--在第一次。