是关于c语言二叉树的,代码运行结果不对,感觉主函数有问题

这个代码不知道哪里错了,感觉应该是主函数的问题,编译不报错但是运行就会有问题

img

就是像这样,输入了。但是无结果,本来它应该继续向下显示一行先序遍历结果的,但是它现在什么也不显示,到底是为什么啊,我觉得是主函数少了什么东西。但是又搞不明白是什么东西。

这个是题目

任务:建立二叉树,并实现二叉树的遍历以及求根结点到指定结点的路径。(要用c语言)

功能要求:

建立二叉树存储结构;
对二叉树进行先序、中序、后序、层序遍历,并输出对应遍历序列;
求根结点到指定结点的路径。
界面要求:程序运行后,给出菜单项的内容和输入提示:

建立二叉树存储结构
求二叉树的先序遍历序列
求二叉树的中序遍历序列
求二叉树的后序遍历序列
求二叉树的层序遍历序列
求根结点到指定结点的路径
退出
请选择0-5:

#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct BiTNode {//二叉树结点
    char data;                      //数据
    struct BiTNode *lchild,*rchild; //左右孩子指针
} BiTNode,*BiTree;
//    链栈 
typedef struct STACK{
    int data;
    struct STACK *next;    
}StackNode,*Stack; 
int flag;    //    标记符 
Stack L;    //    链栈头节点指针 
//************************* 二叉树 ***********************// 
//    创建二叉树 
int nn=0;
int CreateBiTree(BiTree *T) 
{//按先序序列创建二叉树
    char data;
    scanf("%c",&data);//按先序次序输入二叉树中结点的值(一个字符),'#'表示空树
    if (data == '#') 
    {
        *T = NULL;
    } 
    else
     {
        *T = (BiTree)malloc(sizeof(BiTNode)); nn++;
        (*T)->data = data;         //生成根结点
        CreateBiTree(&(*T)->lchild);//构造左子树
        CreateBiTree(&(*T)->rchild);//构造右子树
    }
    return 0;
}
void Visit(BiTree T)
 {//输出
    if (T->data != '#')
     {
        printf("%c ",T->data);
    }
}
void PreOrder(BiTree T) 
{//先序遍历
    if (T != NULL) 
    {
        Visit(T);               //访问根节点
        PreOrder(T->lchild);    //访问左子结点
        PreOrder(T->rchild);    //访问右子结点
    }
}
void InOrder(BiTree T) 
{//中序遍历
    if (T != NULL) 
    {
        InOrder(T->lchild);     //访问左子结点
        Visit(T);               //访问根节点
        InOrder(T->rchild);     //访问右子结点
    }
}
void PostOrder(BiTree T) 
{//后序遍历
    if (T != NULL) {
        PostOrder(T->lchild);   //访问左子结点
        PostOrder(T->rchild);   //访问右子结点
        Visit(T);               //访问根节点
    }
}
typedef struct BiTNodePost{
    BiTree biTree;
    char tag;
} BiTNodePost,*BiTreePost;

void LevelOrder(BiTree T) {//层次遍历
    BiTree p;
    BiTree *queue;
    int h=0,t=0,n=0;
    if (T == NULL) return;
    p=T;
    queue=(BiTree *)malloc(nn*sizeof(BiTree));
    queue[t]=p;t=(t+1)%10;n++;//根节点入队
    while (n) {    //队列不空循环
        p=queue[h];             //对头元素出队
        printf("%c ",p->data);  //访问p指向的结点
        h=(h+1)%10;n--;         //退出队列
        if (p->lchild != NULL) {//左子树不空,将左子树入队
            queue[t]=p->lchild;t=(t+1)%10;n++;
        }
        if (p->rchild != NULL) {//右子树不空,将右子树入队
            queue[t]=p->rchild;t=(t+1)%10;n++;
        }
    }
    free(queue);
}
//************************* 链 栈 *********************//

//    入栈
void PushStack(int x)
{
    Stack top;
    top = (Stack)malloc(sizeof(StackNode));
    top->data = x;
    top->next = L;        //    第一次是让一开始的头节点存入元素,尾巴指向NULL已经初始化好
    L = top;            //    之后便是创建新的链栈节点和之前的串起来
} 

//    出栈
int PopStack()
{
    int x;
    
    if(L->next==NULL)    //    栈空
    {
        printf("出栈完毕\n");
        exit(-1);
    }else{
        
        Stack p;
        x = L->data;
        p = L;            //    让原来的L变成P 
        L = p->next;    //    原来头节点next指向的变成新的头节点 
        free(p);        //    释放原来的头节点 
        return x;        //    返回原来头节点里头的元素 
        
    }
    
} 

//    进入二叉树搜索特定节点
void CherkNode(BiTree T,int dat)
{
    if(T==NULL)
    {
        return;
    }    
    
    if(flag==1)        //    标记符flag 还是1时,表示还没找到要找的节点 
    {
        printf("入栈元素为: %d\n",T->data);
        PushStack(T->data);     //    入栈
    }
    if(T->data == dat)        //    已经在二叉树中遍历到要找的节点元素 
    {
        printf("元素找到,元素为: %d\n",T->data);
        flag = 0;
        return; 
    }
    
    CherkNode(T->lchild,dat);    //    遍历这个节点左子树,为NULL时才结束递归,返回上一级节点
    CherkNode(T->rchild,dat);    //    遍历这个节点的右子树,为NULL时返回上一级节点
    
    if(flag==1)        //    递归遍历二叉树每条路径中寻找,由于遍历一个节点 
    {                //    就会让元素入栈,以便将后面元素不是要找路径之中的元素,从栈中清除 
        printf("出栈元素: %d\n",T->data); 
        PopStack();    //    清除非要寻找路径上的栈中元素    
    }
} 
//    搜索路径 
void SearchPath(BiTree T,int data)
{
    int temp[30];    //    用来存最后找到的路径各个节点里头的数据 
    int i;
    flag = 1;        //    标记符 
    
    L = (Stack)malloc(sizeof(StackNode));    //    分配空间给指针 
    L->next = NULL;        //    让第一个节点指针指向NULL,最后也就是栈底指针 
    
    if(T==NULL)        //    空树 
    {
        return;
    }
    CherkNode(T,data);    //    搜索二叉树中要找的节点,进行入栈出栈操作 
    for(i=0;L->next;i++)
    {
        temp[i] = PopStack();    //    找到的路径元素逆序存放在数组temp[]中 
    } 
    printf("路径寻找成功,路径如下:\n");
    for(i--;i>=0;i--)
    {
        printf("%d ",temp[i]);
    }
}

int main() 
{
    printf("1.建立二叉树存储结构\n2.求二叉树的先序遍历序列\n3.求二叉树的中序遍历序列\n4.求二叉树的后序遍历序列\n5.求二叉树的层序遍历序列\n6.求根结点到指定结点的路径\n0.退出\n");
        BiTree T;
    printf("请输入要选择的功能:");
     setlocale(LC_ALL,"chs"); 
    int choose;
    scanf("%d",&choose);
    switch(choose)
    {
        case 1:{
                printf("请输入二叉树:"); 
                CreateBiTree(&T);
               }
        case 2:{
                  printf("先序遍历:");
                  PreOrder(T);
                  printf("\n");
               }
        case 3:{
                printf("中序遍历:");
                InOrder(T);
                  printf("\n");
               }
        case 4:{
                printf("后序遍历:");
                PostOrder(T);
                printf("\n");
        }
        case 5:{
                printf("层次遍历:");
                LevelOrder(T);
                printf("\n");
               }
        case 6:{BiTree T;                //    创建二叉树指针  
                int Node;
                printf("请输入第一个节点(输入-1表示该节点下无其他节点)\n");
                CreateBiTree(&T);
                printf("先序遍历如下:\n"); 
                PreOrder(T); 
                putchar('\n');
                printf("请输入你要找的特定节点:\n");
                scanf("%d",&Node);
                SearchPath(T,Node);        //    开始搜索节点
                return 0;
                }
        case 0:printf("感谢使用本软件!已正常退出,按任意键结束!\n");breakdefault:printf("无效操作"); 
    }
}


你怎么输入的,是先序遍历输入的么?调试下,看看输入的过程有没有死循环。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7619927
  • 除此之外, 这篇博客: C语言实现八大排序算法详解及其性能之间的中的 这里需要对堆有一定的了解,堆就是一个比较特殊的完全二叉树,在最大堆里,每个节点的值都大于其左右两个孩子节点的值。这就是最大堆。反之就是最小堆。拿最大堆举例子,每次堆顶的元素值,不就是当前数列的最大吗?这不就成选择排序里的简单排序了吗?找完之后,将他和完全二叉树里最后一个结点的值进行交换,然后做一个自顶向下的自我调整,将他再次调整成一个完全二叉堆。第二次取最大的树,这时我们需要将上一次找到的结点屏蔽掉,不然会陷入一个死循环。无数次找完之后,再按层序的思想将二叉树里的数据遍历到一个数组当中,这时的数组为一个有序的数组。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    算法思想

  • 以下回答来自chatgpt:

    这是一个比较复杂的问题,需要仔细分析,先来了解一下二叉树的相关知识。

    二叉树(Binary Tree)是指树中每个节点最多有两个子树的树结构。常被用于实现二叉查找树和二叉堆。二叉树具有以下几个重要的性质:

    1.空树是一个二叉树。 2.每个节点最多有两棵树,左子树和右子树,次序不能颠倒。 3. 左子树以及右子树都是二叉树。 具有以下几个变形:

    1.斜树:当二叉树每个节点都只有左子树,那么这颗二叉树就是一颗左斜树,反之它的每个节点都只有右子树,它就被称为右斜树。 2.满二叉树:在一颗二叉树中,如果所有的分支节点都拥有自己的左子树和右子树,且所有叶子节点都在同一层级上,这样的二叉树被称为优秀的二叉树,满树具有绝美的性质,主要有以下几个特点: 3. 完美二叉树

    在解决这个问题之前,需要了解一下二叉树的实现以及遍历方式。

    一:二叉树的实现

    根据二叉树的定义,我们可以用结构体或者类的方式来表示二叉树,比如:

    struct TreeNode{ int val; struct TreeNode left; struct TreeNode right; };

    class TreeNode{ public: int val; TreeNode left; TreeNode right; };

    二:二叉树的遍历

    遍历,是指按照一定的规律轮流访问树中的每一个节点。常用的二叉树遍历算法一般有:先序遍历、中序遍历、后序遍历、层序遍历。

    1.先序遍历

    先序遍历,又称为前序遍历,按照“根左右”的顺序进行访问。遍历算法的实现很容易通过递归实现。对于每个子节点,先访问它的值,然后遍历其左子树,最后遍历其右子树。

    C语言实现代码如下:

    / TreeNode : 二叉树节点 side : 标记左右子节点, 0代表左子节点, 1代表右子节点 value: 节点的值 / void PreorderTraversal(BiTree T) { if(T) // 当前结点非空 { printf("%c ", T->data); // 输出结点 data 域的值 PreorderTraversal(T->lchild); // 先游走左子树 PreorderTraversal(T->rchild); // 后游走右子树 } }

    2.中序遍历

    中序遍历,又称为中序遍历,按照“左根右”的顺序进行访问。与先序遍历不同的是,在遍历左子树之后,访问根节点,然后再遍历右子树。

    C语言实现代码如下:

    void InorderTraversal(BiTree T) { if(T) // 当前结点非空 { InorderTraversal(T->lchild); // 游走左子树 printf("%c ", T->data); // 输出结点 data 域的值 InorderTraversal(T->rchild); // 游走右子树 } }

    3.后序遍历

    后序遍历,又称为后序遍历,按照“左右根”的顺序进行访问。与先序遍历和中序遍历不同的是,在遍历完左子树和右子树之后,访问根节点。

    C语言实现代码如下:

    void PostorderTraversal(BiTree T) { if(T) // 当前结点非空 { PostorderTraversal(T->lchild); // 游走左子树 PostorderTraversal(T->rchild); // 游走右子树 printf("%c ", T->data); // 输出结点 data 域的值 } }

    4.层序遍历

    层序遍历,又称为广度优先遍历(BFS),按照从上到下,从左到右访问树中的所有节点。遍历算法的实现需要借助队列,对于每个子节点,如果它的左子树非空,则将其插入到队列中,如果它的右子树非空,则同样将其插入到队列中。按顺序从队列中取得节点并访问,直到队列中元素为空。

    Python实现代码如下:

    def LevelOrder(root): if not root: return []

    queue = [root]    # 队列里存放的是节点
    out = []          # 存放遍历的节点值
    while queue:
        node = queue.pop(0)
        out.append(node.val)
    
        if node.left:
            queue.append(node.left)
        if node.right:
            queue.append(node.right)
    
    return out
    

    回到这个问题,出现了菜单项的内容和在运行程序后出现的输入提示,因此应该依据提示选择相应的选项。一些参考代码的实现可以在C++和Python语言中完成。对于二叉树的实现,可以采用结构体或者类的方式表示二叉树,并使用递归的方式进行遍历,对于堆排序和快速排序等高级算法,可以参考常用的算法书籍,或者查找相关资料,具体实现如下:


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^