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

  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;
	}
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目的: 掌握与文件和目录树有关的系统调用和库函数。 要求: 1、编写程序myfind 命令语法: myfind <pathname> [-comp <filename> | -name <str>…] 命令语义: (1)myfind <pathname> 的功能: 除了具有与程序4-7相同的功能外,还要输出在<pathname>目录子树之下,文件长度不大于4096字节的常规文件,在所有允许访问的普通文件中所占的百分比。程序不允许打印出任何路径名。 (2)myfind <pathname> -comp <filename>的功能: <filename>是常规文件的路径名(非目录名,但是其路径可以包含目录)。命令仅仅输出在<pathname>目录子树之下,所有与<filename>文件内容一致的文件的绝对路径名。不允许输出任何其它的路径名,包括不可访问的路径名。 (3)myfind <pathname> -name <str>…的功能: <str>…是一个以空格分隔的文件名序列(不带路径)。命令输出在<pathname>目录子树之下,所有与<str>…序列中文件名相同的文件的绝对路径名。不允许输出不可访问的或无关的路径名。 <pathname>和<filename>均既可以是绝对路径名,也可以是相对路径名。<pathname>既可以是目录,也可以是文件,此时,目录为当前工作目录。 2、注意尽可能地提高程序的效率。注意避免因打开太多文件而产生的错误。 3、遍历目录树时,访问结点(目录项)的具体操作应当由遍历函数dopath携带的函数指针参数决定。这样程序的结构清晰,可扩充性好。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值