所以我正在尝试进行三元搜索。现在,我只是在处理插入功能。我已经理解了网上三元搜索的基本思想。我知道一个根节点有3个叶子,如果角色在根之前,它会在左边,在右边之后,如果它与根匹配,它会到达中间叶子。因此,我的主要目标是制作一个程序,可以为错误拼写的用户输入的单词建议单词。但目前我正在努力制作三元搜索特里。我使用trie制作一本字典,用它来检查用户输入的单词以建议下一个最佳选择。但是现在,只需要将一些字符输入到三元组中,当我显示它时,应该按顺序显示它。 我不是100%肯定我对中叶的逻辑。现在我的程序在运行时,给了我一些垃圾无限值,以某种方式与输入的最后一个字符相关。我不知道我哪里出错了。有人可以指出我犯了哪些错误吗?另外,如果我写的任何逻辑都错了,你能告诉我吗?我的意思是,你不必给我代码或任何东西,因为一旦我明白我出错了,我觉得自己有能力做到这一点,但如果有人能帮助我找到错误,那将有助于我很多!
整个代码:
#include <stdio.h>
#include <stdlib.h> //Because usage of malloc gives warnings without this header
typedef struct tstree
{
struct tstree *lokid;
struct tstree *hikid;
struct tstree *eqkid;
char letter;
}node;
node *head = NULL;
int count = 0;
int insert(char x, node **head)
{
if (*head==NULL) //If it's the first element
{
*head = malloc(sizeof(node));
(*head)->letter = x;
count++;
(*head)->lokid = (*head)->hikid = (*head)->eqkid = NULL; //Assign all 3 to null initially
}
else if ((*head)->letter == x) //If equal, insert below
insert(x , &((*head)->eqkid) );
else if ((*head)->letter > x) //If inserted char comes before current val, insert to left
insert(x,&(*head)->lokid);
else
insert(x,&(*head)->hikid); //Else to the right
return 0;
}
void display(node *head)
{
if(head)
{
display(head->lokid); //print in infix order
printf("%c ",head->letter);
display(head->hikid);
}
//return 0;
}
int main()
{
int op;
char num;
printf("\nWelcome Fabiz. Hope it meets your expectations!\n");
while(1)
{
printf("\n1. To insert an element\n2. Display the tree\n3. Exit\nOption :");
scanf("%d",&op);
switch(op)
{
case 1:
{
system("clear");
printf("\nEnter the element : ");
scanf(" %c",&num);
insert(num,&head);
break;
}
case 2:
{
system("clear");
if(count == 0)
printf("\nEmpty tree\n");
else
{
printf("Display in order..\n");
display(head);
}
break;
}
default: exit(0);
}
}
return 0;
}
我正在使用Geany文本编辑器,我在Linux Mint上。我遇到了一个问题,在编译器中只打印出我点击显示功能时无限输入的最后一个字符。 任何帮助都会非常有帮助! 谢谢!
答案 0 :(得分:3)
您的显示功能有误。循环条件永远不会计算为false:
while(&(*head)->lokid!=NULL && &(*head)->hikid!=NULL)
这不是你想要的。 &(*head)->lokid
或&(*head)->hikid
无法评估为NULL
。如果head
不是NULL
,则&(*head)->lokid
与*head
的地址相同,加上lokid
中struct tstree
的偏移量。请注意,您的循环甚至没有可能使条件为假的更新语句,并且它没有任何break
- 它注定要失败。
事实上,你甚至根本不需要循环。要按顺序打印,这就是您所需要的:
void display(node *head) {
if (head) {
display(head->lokid);
printf("%c ", head->letter);
display(head->hikid);
}
}
请注意,传递node **
没有任何意义(我将其更改为node *
),返回值应为void
。
<强>更新强>
您的insert()
函数是正确的,但您在main
中使用了错误的变量。来自insert()
的递归基础中的此赋值导致意外行为:
temp = *head = malloc(sizeof(node));
请注意,每次点击基本案例时,都会将新节点分配给*head
和temp
,从而失去对temp
之前存储的内容的引用。然后你拨打display(temp)
。是的,您构建了trie,但是从最后插入的节点开始打印它 - 而不是您想要的。
相反,您应该使用全局变量display
调用head
,这是您的trie的正确根目录:
display(head);
调用insert时会发生同样的情况。您不希望在最后添加的节点上插入新的字母,您希望在根上添加它。 main()
应该改为:
insert(num, &head);
虽然我们已经注意到了,但请注意temp
完全没必要。你不需要它。 insert
通过引用操纵全局头,temp
在这里没用(事实上它引入了一个bug)。
在main中更改这两行就足够了,在这里进行测试,它就像魅力一样。