C 三元搜索trie插入函数问题

C 三元搜索trie插入函数问题,c,trie,ternary-search-tree,C,Trie,Ternary Search Tree,所以我想做一个三元搜索。现在,我只处理insert函数。我已经理解了三元搜索trie的基本思想。我知道一个根节点有3片叶子,如果角色在根之前,它会在左,右之后,如果它与根匹配,它会在中间的叶子。所以我的主要目标是制作一个程序,可以为拼写错误的用户输入的单词提供建议。但目前我正在做三元搜索。我使用trie制作了一个字典,用它检查用户输入的单词,以建议下一个最佳选择。但是现在,只需要在三元trie中输入一些字符,当我显示它时,它应该按顺序显示。 关于中间叶,我不能100%确定我的逻辑。现在,当我的程

所以我想做一个三元搜索。现在,我只处理insert函数。我已经理解了三元搜索trie的基本思想。我知道一个根节点有3片叶子,如果角色在根之前,它会在左,右之后,如果它与根匹配,它会在中间的叶子。所以我的主要目标是制作一个程序,可以为拼写错误的用户输入的单词提供建议。但目前我正在做三元搜索。我使用trie制作了一个字典,用它检查用户输入的单词,以建议下一个最佳选择。但是现在,只需要在三元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;
}
#包括
#include//因为使用malloc会发出警告,而不使用此标题
类型定义结构tstree
{
结构tstree*lokid;
结构tstree*hikid;
结构tstree*eqkid;
字符字母;
}节点;
node*head=NULL;
整数计数=0;
int insert(字符x,节点**头)
{
if(*head==NULL)//如果是第一个元素
{
*head=malloc(sizeof(node));
(*标题)->字母=x;
计数++;
(*head)->lokid=(*head)->hikid=(*head)->eqkid=NULL;//最初将所有3个赋值为NULL
}
else if((*head)->字母==x)//如果相等,则在下面插入
插入(x,&(*头)->eqkid);
else if((*head)->letter>x)//如果插入的字符位于当前val之前,则向左插入
插入(x,&(*头部)->lokid);
其他的
插入(x,&(*head)->hikid);//右侧的Else
返回0;
}
无效显示(节点*头部)
{
若有(总目)
{
显示(head->lokid);//按中缀顺序打印
printf(“%c”,标题->字母);
显示(头部->hikid);
}
//返回0;
}
int main()
{   
int op;
字符数;
printf(“\n欢迎光临法比兹。希望它能满足您的期望!\n”);
而(1)
{
printf(“\n1.插入元素\n2.显示树\n3.退出\n选项:”);
scanf(“%d”和&op);
开关(op)
{
案例1:
{
系统(“清除”);
printf(“\n输入元素:”);
scanf(“%c”和&num);
插入(数字和头部);
打破
}
案例2:
{
系统(“清除”);
如果(计数=0)
printf(“\n目录树\n”);
其他的
{
printf(“按顺序显示..\n”);
显示器(头部);
}
打破
}
默认值:退出(0);
}
}
返回0;
}
我使用的是Geany文本编辑器,我使用的是LinuxMint。我遇到了一个问题,在编译器中,当我点击display函数时,只打印我输入的最后一个字符。 任何帮助都会很有帮助!
谢谢

您的显示功能错误。循环条件的计算结果从不为false:

while(&(*head)->lokid!=NULL && &(*head)->hikid!=NULL)
这不是你想要的。任何
&(*head)->lokid
&(*head)->hikid
都不会计算为
NULL
。如果
head
不是
NULL
,那么
&(*head)->lokid
就是
*head
加上
struct tstree
lokid
的偏移量的地址。请注意,您的循环甚至没有可能使条件为false的update语句,并且没有任何
中断
——这是注定的

事实上,你甚至不需要一个循环。要按顺序打印,您只需执行以下操作:

void display(node *head) {
    if (head) {
        display(head->lokid);
        printf("%c ", head->letter);
        display(head->hikid);
    }
}
请注意,传递
节点**
(我将其更改为
节点*
)没有任何意义,返回值应为
void

更新

您的
insert()
函数是正确的,但在
main
中使用了错误的变量。来自
insert()
的递归基中的此赋值导致意外行为:

temp = *head = malloc(sizeof(node));
请注意,每次点击基本大小写时,都会将一个新节点分配给
*head
temp
,从而丢失对以前存储在
temp
中的内容的引用。然后调用
display(temp)
。是的,您构建了trie,但是您正在从最后一个插入的节点开始打印它,而不是您想要的

相反,您应该使用全局变量
head
调用
display
,该变量是trie的正确根:

display(head);
调用insert时也会发生同样的情况。您不希望插入从最后添加的节点开始的新字母,而是希望从根节点开始添加新字母
main()
应改为:

insert(num, &head);
当我们这样做的时候,请注意,
temp
是完全没有必要的。你不需要它
insert
通过引用操作全局头,
temp
在这里没有用处(事实上它引入了一个bug)


主要更改这两行就足够了,在这里进行测试,它的工作效果非常好。

哦!戴恩。事实上,我一开始就是这么做的。这只是我的实验。但是,是的,我把它改回了if(head)并使它成为单指针。这只是一个单指针类型函数的原因是,我们实际上不需要编辑trie/添加到trie中的任何内容,因此不需要使用n