【数据结构】二叉树遍历与路径查找

  1. 实现功能:建立二叉树存储结构、求二叉树的先序遍历、求二叉树的中序遍历、求二叉树的后序遍历、求二叉树的层次遍历、求根到给定结点的路径。
  2. 设计要求:

数据结构:

typedef struct  node{

       char data; //数据域

       struct node *lchild ,  *rchild;  //左右孩子指针

}BinTNode, *BinTree;   //树中结点类型

首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。

程序运行后,给出如下菜单项的内容和输入提示,使用数字0—6来选择菜单项,其它输入则不起作用:

1.建立二叉树存储结构

2.求二叉树的先序遍历

3.求二叉树的中序遍历

4.求二叉树的后序遍历

5.求二叉树的层次遍历

6.求给定结点的路径

0.退出系统

请选择0—6:

#include<stdio.h>
#include<string.h>
#include<conio.h>	//内含getch() 
#include<iostream> 
#include<malloc.h>	//内含malloc 

typedef struct BinTNode{
	char data;
	struct BinTNode *lchild ,  *rchild; 
}BinTNode, *BinTree;   //树中结点类型
//链栈
typedef struct StackNode{
	BinTree data;
	struct StackNode *next;
}StackNode,*LinkStack; 

void print();
void CreateBinTree(BinTree &T,int num,char c);
void InOrderTraverse(BinTree &T);
void MidOrderTraverse(BinTree &T);
void LastOrderTraverse(BinTree &T);
void LevelOrder(BinTree &T);
bool FindPath(BinTree &T,LinkStack &S,char x);
bool ReFindPath(BinTree &T,LinkStack &S,char x,int m0);
int NodeCount(BinTree &T);
//以下为链栈的操作 
void InitStack(LinkStack &S); 
void Push(LinkStack &S,BinTree e);
void Pop(LinkStack &S);
void Get(LinkStack &S);

BinTree tree;
LinkStack S;
int n=0,m=0;	//n为所查询结点个数,m为查询路径循环次数 

int main(){
	while(1){
		print();
		char c = getch();	//getch()返回从stdin读取的字符的ASCII值,如:输入字符'0',它将返回48; 
		int num;
		if(c>'6'||c<'0'){
            printf("\n请输入0-6之内的数字!\n");
            continue;
		}
		else{
			//在C/C++中,可以将字符直接转换成整数
			/* 
			num = c;
			printf("%d\n",num);	//输出49 
			*/
			num = c-'0';
			//printf("%d\n",num);	//输出1 
		}      
        if(num==1){
        	printf("\n请输入你要输入的树序列:\n");
            CreateBinTree(tree,0,0);
            if(tree==NULL){
            	printf("树为空树,请重新建立"); 
			}
			else{
				printf("\n创建树完毕!\n");
				InOrderTraverse(tree);
			}  
        }
        else if(num==2){
        	if(tree==NULL){
            	printf("树为空树,请重新建立"); 
			}
			else{
				printf("\n输出先序:");
            InOrderTraverse(tree);
            printf("\n");
			}
        }
		else if(num==3){
			if(tree==NULL){
            	printf("树为空树,请重新建立"); 
			}
			else{
				printf("\n输出中序:");
            	MidOrderTraverse(tree);
            	printf("\n");
			}
		}
		else if(num==4){
			if(tree==NULL){
            	printf("树为空树,请重新建立"); 
			}
			else{
				printf("\n输出后序:");
            LastOrderTraverse(tree);
            printf("\n");
			}
		}
		else if(num==5){
			if(tree==NULL){
            	printf("树为空树,请重新建立"); 
			}
			else{
				 printf("\n输出层序遍历:");
            	LevelOrder(tree);
            	printf("\n");
			}
		}
		else if(num==6){
			if(tree==NULL){
            	printf("树为空树,请重新建立"); 
			}
			else{
				int nodecon=NodeCount(tree);
			InitStack(S);
			printf("\n请输入要查询的结点");
			char ch;
			ch=getch();
			printf("%c",ch);
			bool b;
			m=0;
            b=FindPath(tree,S,ch);
            if(!b){
            	printf("\n未查询到目标结点"); 
			}
			else if(m<nodecon){
				while(m<nodecon){
					n++;
					printf("\n-------\n"); 
					Get(S);
					int m0=m;	//m0暂存m值 
					m=0;	//m重新计数 
					ReFindPath(tree,S,ch,m0);
				}
			}
			printf("\n--------\n"); 
			Get(S);	
			}
		}
        else if(num==0){
		    break;
		}
	}
	return 0;
}

void print()
{	
	printf("\n");
    printf("***************************************\n");
    printf("   ————[ 树操作功能栏 ]————\n");
    printf("***************************************\n");
    printf("*        1.建立二叉树存储结构        *\n");
    printf("*        2.求二叉树的先序遍历        *\n");
    printf("*        3.求二叉树的中序遍历        *\n");
    printf("*        4.求二叉树的后序遍历        *\n");
    printf("*        5.求二叉树的层次遍历        *\n");
    printf("*        6.求根到给定结点的路径      *\n");
    printf("*        0. 退出系统                  *\n");
    printf("---------------------------------------\n");
    printf("      请输入0-6选择功能:");
}

void CreateBinTree(BinTree &T,int num,char c)
{
	//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
	if(num==1)
        printf("\n请输入%c的左孩子,#代表空:\n",c);
    else if(num==2)
        printf("\n请输入%c的右孩子,#代表空:\n",c);
	char ch;
	ch=getch();
	printf("%c",ch);
	if(ch=='#'){
        T=NULL;
	}			//递归结束,建空树
	else
	{
		T=new BinTNode;	//生成根结点
		T->data=ch;					
		CreateBinTree(T->lchild,1,T->data);	//递归创建左子树
		CreateBinTree(T->rchild,2,T->data);	//递归创建右子树
	}								
}

void InOrderTraverse(BinTree &T)
{
	//先序遍历二叉树T的递归算法
	if(T)
	{
		printf("%c",T->data);
		InOrderTraverse(T->lchild);
		InOrderTraverse(T->rchild);
	}
}

void MidOrderTraverse(BinTree &T)
{
	//中序遍历二叉树T的递归算法
	if(T)
	{
		MidOrderTraverse(T->lchild);
		printf("%c",T->data);
		MidOrderTraverse(T->rchild);
	}
}

void LastOrderTraverse(BinTree &T)
{
	//中序遍历二叉树T的递归算法
	if(T)
	{
		LastOrderTraverse(T->lchild);
		LastOrderTraverse(T->rchild);
		printf("%c",T->data);
	}
}

void LevelOrder(BinTree &Tree)  {
	if(Tree==NULL)
        return;
    BinTree s[100];
    int front, rear;	//front头指针,rear尾指针 
    front = rear = -1; //采用顺序队列,并假定不会发生溢出
    s[++rear] = Tree;
    while(front != rear){	 
        BinTree q = s[++front];	//q为头指针所指,每经过一轮循环,收集头指针的左右孩子
        printf("%c",q->data);

        if (q->lchild)
            s[++rear] = q->lchild;

        if (q->rchild)
            s[++rear] = q->rchild;
    }
}
bool FindPath(BinTree &T,LinkStack &S,char x){	//用链栈
	m++;
	bool b=false;	  
	if(T==NULL){
		return false;
	}
	Push(S,T);	//入栈 
	if(T->data == x){
		return true;
	}
	//先去左子树找
	if(T->lchild != NULL){
		b = FindPath(T->lchild,S,x);
	}
	//左子树找不到并且右子树不为空的情况下才去找   
    if(!b && T->rchild != NULL){
		b = FindPath(T->rchild,S,x);
	}   
	//左右都找不到,弹出栈顶元素     
    if(!b){
    	Pop(S);	//不符,出栈 
	} 
    return b;
}
bool ReFindPath(BinTree &T,LinkStack &S,char x,int m0){
	m++;
	bool b=false;	  
	if(T==NULL){
		return false;
	}
	Push(S,T);	//入栈 
	if(T->data == x){
		if(m<=m0){
			
		}
		else{
			return true;
		}	
	}
	//先去左子树找
	if(T->lchild != NULL){
		b = ReFindPath(T->lchild,S,x,m0);
	}
	//左子树找不到并且右子树不为空的情况下才去找   
    if(!b && T->rchild != NULL){
		b = ReFindPath(T->rchild,S,x,m0);
	}   
	//左右都找不到,弹出栈顶元素     
    if(!b){
    	Pop(S);	//不符,出栈 
	} 
    return b;
}
void InitStack(LinkStack &S){
	S=NULL;
	return;
}
void Push(LinkStack &S,BinTree e){
	//在栈顶插入e
	StackNode* p = (StackNode *)malloc(sizeof(StackNode));
	p->data=e;
	p->next=S;
	S=p;	//修改栈顶指针为p 
	return;
}
void Pop(LinkStack &S){
	//删除S的栈顶元素
	if(S==NULL){
		return;
	} 
	StackNode* p =S;	//用p临时保存栈顶空间,以备释放 
	S=S->next;	//修改栈顶指针
	delete p;	//释放原栈顶元素的空间
	return;	
}
void Get(LinkStack &S){
	printf("\n");
	while(1){
		if(S!=NULL){
			printf("%c",S->data->data);
			Pop(S);
		}
		else{
			break;
		}
	}
}
int NodeCount(BinTree &T){
	if(T==NULL){
		return 0;
	}
	else{
		return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
	}
}

posted @ 2022-01-04 16:36  轻闲一号机  阅读(10)  评论(0)    收藏  举报  来源