这个代码不知道哪里错了,感觉应该是主函数的问题,编译不报错但是运行就会有问题
就是像这样,输入了。但是无结果,本来它应该继续向下显示一行先序遍历结果的,但是它现在什么也不显示,到底是为什么啊,我觉得是主函数少了什么东西。但是又搞不明白是什么东西。
这个是题目
任务:建立二叉树,并实现二叉树的遍历以及求根结点到指定结点的路径。(要用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");break;
default:printf("无效操作");
}
}
你怎么输入的,是先序遍历输入的么?调试下,看看输入的过程有没有死循环。
不知道你这个问题是否已经解决, 如果还没有解决的话:这是一个比较复杂的问题,需要仔细分析,先来了解一下二叉树的相关知识。
二叉树(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语言中完成。对于二叉树的实现,可以采用结构体或者类的方式表示二叉树,并使用递归的方式进行遍历,对于堆排序和快速排序等高级算法,可以参考常用的算法书籍,或者查找相关资料,具体实现如下: