# 数据结构课程设计大曝光(4) **注:转发请注明出处,以免老师误以为本人抄袭……** [TOC] # 课程设计四 二叉树的遍历 ## 一、实习目的和任务: ### 【问题描述】 设计一个程序演示在二叉树上进行三种遍历的过程。 ### 【基本要求】 - (1)从键盘上输入二叉树的每一个结点,演示二叉树T的建立过程。 - (2)演示各种遍历的遍历过程。 ## 二、概要设计: **设计思路:仿照tree命令输出的文件夹树输出和创建二叉树,利用递归或栈和循环先序,中序,后序遍历二叉树,利用队列层次遍历二叉树** ### 1、栈的顺序存储结构实现 ```C //-----------------栈的顺序存储结构 定义 开始----------------------- typedef int SElemType; #define STACK_INIT_SIZE 100//存储空间初始分配量 #define STACKINCREMENT 100//存储空间分配增量 typedef struct{ SElemType * base;//在栈构造之前和销毁之后,base的值为NULL SElemType *top;//栈顶指针 int stacksize;//当前已分配的存储空间,以元素为单位 }SqStack; //-------------------------------栈的顺序存储结构 定义 结束--------------------- //------------------栈的顺序存储结构 基本操作的实现 开始-------------------- Status InitStack(SqStack &S){ //构造一个空栈S Status ClearStack(SqStack &S) //把S置为空栈 Status StackEmpty(SqStack S) //若栈S为空栈,则返回TRUE,否则返回FALSE int StackLenth(SqStack &S) //返回S的元素个数,即栈的长度 Status StackTraverse(SqStack &S,Status(*visit)(SElemType &e)) //从栈底到栈顶依次对栈中每一个元素调用函数visit() //一旦visit()失败,则返回ERROR Status GetTop(SqStack S,SElemType &e){ //若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR Status Push(SqStack &S,SElemType e){ //插入元素e为新的栈顶元素 Status Pop(SqStack &S,SElemType &e) //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR void DestroyStack(SqStack &S) //销毁栈S Status PutElem(SElemType &e) //输出元素e void PrintStack(SqStack &S) //从栈底依次显示栈中的所有元素,不对栈作任何修改 //--------------栈的顺序存储结构 基本操作的实现 结束-------------------------- ``` ### 2、循环队列--队列的顺序存储结构 ```C //------------------循环队列--队列的顺序存储结构 定义 开始--------------------- #define MAXQSIZE 16384//队列的最大容量 typedef struct{ ElemType * data;//初始化的动态分配存储空间 int front;//头指针,若队列不空,指向队列头元素 int rear;//尾指针,若队列不空,指向队列尾元素 }Queue; //------------------循环队列--队列的顺序存储结构 定义 开始--------------------- //--------------循环队列--队列的顺序存储结构 基本操作 开始--------------------- Status InitQueue(Queue &Q) //构造一个空队列q Status DestroyQueue(Queue &Q) //销毁队列 int QueueLenth(Queue Q) //返回Q的元素个数,即队列长度 Status EnQueue(Queue &Q,ElemType e) //插入元素e为Q的新的队尾元素 Status DeQueue(Queue &Q,ElemType &e) //若队列不空,则删除Q的队头元素,用e返回其值,并返回OK; //否则返回ERROR Status emptyQueue(Queue &Q) //返回队列是否为空 Status fullQueue(Queue &Q) //返回队列是否已满 //------------------循环队列--队列的顺序存储结构 基本操作 结束----------------- ``` ### 3.二叉树链式结构实现: ```C //--------------------二叉树的二叉链表存储表示 开始----------------------------- typedef struct BiTNode{ ElemType data;//数据元素 struct BiTNode *lchild,*rchild;//左右孩子指针 }BiTNode,*BiTree; //--------------------二叉树的二叉链表存储表示 结束----------------------------- //------------------------二叉树基本操作实现 开始----------------------------- #define MAXLAYER 15//最大层次 int lmark[MAXLAYER];//此层是否结束的标志,用于二叉树的输出 Status output(ElemType &e) //输出二叉树结点,用做遍历函数 Status CreateBiTree(BiTree &T,int n) //按先序输入二叉树中节点的值,空格字符表示空树,构造二叉链表表示的二叉树T,首次调用n为0 void DestroyTree(BiTree &T) //销毁二叉树 Status PreOrderTraverse(BiTree T,Status(*visit)(ElemType &e)) //采用二叉链表存储结构,vist是对节点操作的应用函数 //先序遍历二叉树T,对每个节点调用函数Visit一次且仅一次 //一旦visit()失败,则操作失败 //递归算法 Status InOrderTraverse(BiTree T,Status(*visit)(ElemType &e)) //采用二叉链表存储结构,vist是对节点操作的应用函数 //中序遍历二叉树T,对每个节点调用函数Visit一次且仅一次 //一旦visit()失败,则操作失败 //递归算法 Status PostOrderTraverse(BiTree T,Status(*visit)(ElemType &e)) //采用二叉链表存储结构,vist是对节点操作的应用函数 //后序遍历二叉树T,对每个节点调用函数Visit一次且仅一次 //一旦visit()失败,则操作失败 //递归算法 Status LevelOrderTraverse(BiTree T,Status(*visit)(ElemType &e)) //采用二叉链表存储结构,vist是对节点操作的应用函数 //层次遍历二叉树T,对每个节点调用函数Visit一次且仅一次 //一旦visit()失败,则操作失败 Status preOrderTraverse(BiTree T,Status(* visit)(ElemType &e)) //采用二叉链表存储结构,visit是对数据元素操作的应用函数 //先序遍历二叉树T的非递归算法,对每个数据元素调用函数visit //递归算法 Status inOrderTraverse(BiTree T,Status(* visit)(ElemType &e)) //采用二叉链表存储结构,visit是对数据元素操作的应用函数 //中序遍历二叉树T的非递归算法,对每个数据元素调用函数visit //非递归算法 Status postOrderTraverse(BiTree T,Status(* visit)(ElemType &e)) //采用二叉链表存储结构,visit是对数据元素操作的应用函数 //后序遍历二叉树T的非递归算法,对每个数据元素调用函数visit //非递归算法 void printBiTree(BiTree T,int n) //将二叉树以树的结构输出,首次调用n为0 //模式1,实线为左子树,虚线为右子树 void printBiTree2(BiTree T,int n) //将二叉树以树的结构输出,首次调用n为0 //模式2,先左子树后右子树,没有显示空 //------------------栈的顺序存储结构 基本操作的实现 结束-------------------- ``` ### 4、用户交互的实现: - char precmd[]---------------------------------定义用户可以使用的命令 - int isCmd(char cmd) ------------------------判断是否为可识别的命令,即是否存在于precmd中 - void Pause() ----------------------------------暂停并按任意键继续 - void Help() ------------------------------------输出命令帮助 - void openScreen()-----------------------------输出开始界面 - void Goodbye(BiTree &t) ------------------退出界面并完成销毁工作 - void CMDtran(char c,BiTree &t) ---------解释命令并执行 - char inCMD()---------------------------------命令输入函数 ## 三、程序代码: ```C /*----------------------------------------------------------- Name: 二叉树的遍历 Copyleft: huaying1988.com Author: huaying1988.com Date: 03-07-08 11:33 Description: 【问题描述】 设计一个程序演示在二叉树上进行三种遍历的过程。 【基本要求】 (1)从键盘上输入二叉树的每一个结点,演示二叉树T的建立过程。 (2)演示各种遍历的遍历过程。 -----------------------------------------------------------*/ #include "stdio.h" #include "stdlib.h" #include "conio.h" #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 //Status 是函数的类型,其值是函数结果状态代码 typedef int Status; typedef int ElemType;//定义元素类型 //-----------------—栈的顺序存储结构 定义 开始—————----------------------- typedef int SElemType; #define STACK_INIT_SIZE 100//存储空间初始分配量 #define STACKINCREMENT 100//存储空间分配增量 typedef struct{ SElemType * base;//在栈构造之前和销毁之后,base的值为NULL SElemType *top;//栈顶指针 int stacksize;//当前已分配的存储空间,以元素为单位 }SqStack; //-------------------------------栈的顺序存储结构 定义 结束--------------------- //------------------—栈的顺序存储结构 基本操作的实现 开始-------------------- Status InitStack(SqStack &S){ //构造一个空栈S S.base=(SElemType *)malloc(STACK_INIT_SIZE *sizeof(SElemType)); if(!S.base)exit(OVERFLOW);//存储分配失败 S.top=S.base; S.stacksize=STACK_INIT_SIZE; return OK; }//InitStack Status ClearStack(SqStack &S)//把S置为空栈 { if(S.top=S.base) return OK; else return ERROR; }//ClearStack Status StackEmpty(SqStack S) {//若栈S为空栈,则返回TRUE,否则返回FALSE if(S.top==S.base) return TRUE; else return FALSE; }//StackEmpty int StackLenth(SqStack &S) {//返回S的元素个数,即栈的长度 return S.top-S.base; }//StackLenth Status StackTraverse(SqStack &S,Status(*visit)(SElemType &e)) {//从栈底到栈顶依次对栈中每一个元素调用函数visit(),一旦visit()失败,则返回ERROR SElemType *p; for(p=S.base;p!=S.top;p++) { if(!visit( (*p) ))return ERROR; }//for return OK; }//StackTraverse Status GetTop(SqStack S,SElemType &e){ //若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR if(S.top==S.base)return ERROR; e=*(S.top-1); return OK; }//GetTop Status Push(SqStack &S,SElemType e){ //插入元素e为新的栈顶元素 if(S.top-S.base>=S.stacksize){ //栈满,追加存储空间 S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType)); if(!S.base)exit(OVERFLOW);//存储分配失败 S.top=S.base+S.stacksize; S.stacksize+=STACKINCREMENT; }//if *S.top++ =e; return OK; }//Push Status Pop(SqStack &S,SElemType &e) {//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR if(S.top==S.base) return ERROR; e=* --S.top; return OK; }//Pop void DestroyStack(SqStack &S)//销毁栈S { if(!S.base)free(S.base); S.base=NULL; S.top=NULL; S.stacksize=0; }//DestroyStack Status PutElem(SElemType &e)//输出元素e { if(putchar(e)) return OK; else return ERROR; }//PutElem void PrintStack(SqStack &S) {//从栈底依次显示栈中的所有元素,不对栈作任何修改 StackTraverse(S,PutElem); putch('\n'); }//PrintStack //--------------栈的顺序存储结构 基本操作的实现 结束-------------------------- //------------------循环队列--队列的顺序存储结构 定义 开始--------------------- #define MAXQSIZE 16384//队列的最大容量 typedef struct{ ElemType * data;//初始化的动态分配存储空间 int front;//头指针,若队列不空,指向队列头元素 int rear;//尾指针,若队列不空,指向队列尾元素 }Queue; //------------------循环队列--队列的顺序存储结构 定义 开始--------------------- //--------------循环队列--队列的顺序存储结构 基本操作 开始--------------------- Status InitQueue(Queue &Q) {//构造一个空队列q Q.data=(ElemType *)malloc(MAXQSIZE*sizeof(ElemType)); if(!Q.data)exit(OVERFLOW);//存储分配失败 Q.front=0; Q.rear=0; return OK; }//InitQueue Status DestroyQueue(Queue &Q) {//销毁队列 if(Q.data)free(Q.data); } int QueueLenth(Queue Q) {//返回Q的元素个数,即队列长度 return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE; }//QueueLenth Status EnQueue(Queue &Q,ElemType e) {//插入元素e为Q的新的队尾元素 if((Q.rear+1)%MAXQSIZE==Q.front)return ERROR;//队列满 Q.data[Q.rear]=e; Q.rear=(Q.rear+1)%MAXQSIZE; return OK; }//EnQueue Status DeQueue(Queue &Q,ElemType &e) {//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK; //否则返回ERROR if(Q.front==Q.rear)return ERROR;//队空 e=Q.data[Q.front]; Q.front=(Q.front+1)%MAXQSIZE; return OK; } Status emptyQueue(Queue &Q) {//返回队列是否为空 if(Q.front==Q.rear)return TRUE;//队空 else return FALSE; } Status fullQueue(Queue &Q) {//返回队列是否已满 if((Q.rear+1)%MAXQSIZE==Q.front)return TRUE;//队列满 else return FALSE; } //------------------循环队列--队列的顺序存储结构 基本操作 结束----------------- //--------------------二叉树的二叉链表存储表示 开始----------------------------- typedef struct BiTNode{ ElemType data;//数据元素 struct BiTNode *lchild,*rchild;//左右孩子指针 }BiTNode,*BiTree; //--------------------二叉树的二叉链表存储表示 结束----------------------------- //------------------------二叉树基本操作实现 开始----------------------------- #define MAXLAYER 15//最大层次 int lmark[MAXLAYER];//此层是否结束的标志,用于二叉树的输出 Status output(ElemType &e) {//输出二叉树结点,用做遍历函数 putch(e); return OK; }//output Status CreateBiTree(BiTree &T,int n) {//按先序输入二叉树中节点的值,空格字符表示空树,构造二叉链表表示的二叉树T,首次调用n为0 int i; char a; if(n>=MAXLAYER)a=' '; else a=getch(); while(!(a>=32&&a<=126))a=getch(); if(a!=' '){ putch(a); printf("\n"); T=(BiTree)malloc(sizeof(BiTNode)); T->data=a; for(i=0;i<n;i++){ if(lmark[i]==0)printf("│ "); else printf(" "); }//for printf("├─"); lmark[i]=0; CreateBiTree(T->lchild,n+1); for(i=0;i<n;i++){ if(lmark[i]==0)printf("│ "); else printf(" "); }//for printf("└─"); lmark[i]=1; CreateBiTree(T->rchild,n+1); }//if else{ printf("无\n"); T=NULL; }//else return OK; }//CreateBiTree void DestroyTree(BiTree &T) {//销毁二叉树 if(T){ if(T->lchild)DestroyTree(T->lchild); if(T->rchild)DestroyTree(T->rchild); free(T); } }//DestroyTree Status PreOrderTraverse(BiTree T,Status(*visit)(ElemType &e)) {//采用二叉链表存储结构,vist是对节点操作的应用函数 //先序遍历二叉树T,对每个节点调用函数Visit一次且仅一次 //一旦visit()失败,则操作失败 //递归算法 if(T){ if(visit(T->data)) if(PreOrderTraverse(T->lchild,visit)) if(PreOrderTraverse(T->rchild,visit)) return OK; return ERROR; }//if else return OK; }//PreOrderTraverse Status InOrderTraverse(BiTree T,Status(*visit)(ElemType &e)) {//采用二叉链表存储结构,vist是对节点操作的应用函数 //中序遍历二叉树T,对每个节点调用函数Visit一次且仅一次 //一旦visit()失败,则操作失败 //递归算法 if(T){ if(InOrderTraverse(T->lchild,visit)) if(visit(T->data)) if(InOrderTraverse(T->rchild,visit)) return OK; return ERROR; }//if else return OK; }//InOrderTraverse Status PostOrderTraverse(BiTree T,Status(*visit)(ElemType &e)) {//采用二叉链表存储结构,vist是对节点操作的应用函数 //后序遍历二叉树T,对每个节点调用函数Visit一次且仅一次 //一旦visit()失败,则操作失败 //递归算法 if(T){ if(PostOrderTraverse(T->lchild,visit)) if(PostOrderTraverse(T->rchild,visit)) if(visit(T->data)) return OK; return ERROR; }//if else return OK; }//InOrderTraverse Status LevelOrderTraverse(BiTree T,Status(*visit)(ElemType &e)) {//采用二叉链表存储结构,vist是对节点操作的应用函数 //层次遍历二叉树T,对每个节点调用函数Visit一次且仅一次 //一旦visit()失败,则操作失败 Queue q; BiTree b; InitQueue(q); if(T)EnQueue(q,(int)T); while(!emptyQueue(q)){ // printf("1\n"); if(DeQueue(q,(int &)b)){ if(visit(b->data)){ if(b->lchild)EnQueue(q,(int)b->lchild); if(b->rchild)EnQueue(q,(int)b->rchild); }//if(visit) }//if(DeQueue) }//while DestroyQueue(q); return OK; }//LevelOrderTraverse Status preOrderTraverse(BiTree T,Status(* visit)(ElemType &e)) {//采用二叉链表存储结构,visit是对数据元素操作的应用函数 //先序遍历二叉树T的非递归算法,对每个数据元素调用函数visit //递归算法 SqStack S;InitStack(S);BiTree p=T; while(p||!StackEmpty(S)){ if(p){ if(!visit(p->data)) return ERROR; Push(S,(SElemType)p); p=p->lchild; }//if(p)根指针进栈,遍历左子树 else{//根指针退栈,访问根节点,遍历右子树 Pop(S,(SElemType &)p); p=p->rchild; }//else }//while return OK; }//preOrderTraverse Status inOrderTraverse(BiTree T,Status(* visit)(ElemType &e)) {//采用二叉链表存储结构,visit是对数据元素操作的应用函数 //中序遍历二叉树T的非递归算法,对每个数据元素调用函数visit //非递归算法 SqStack S;InitStack(S);BiTree p=T; while(p||!StackEmpty(S)){ if(p){Push(S,(SElemType)p);p=p->lchild;}//根指针进栈,遍历左子树 else{//根指针退栈,访问根节点,遍历右子树 Pop(S,(SElemType &)p); if(!visit(p->data))return ERROR; p=p->rchild; }//else }//while return OK; }//inOrderTraverse Status postOrderTraverse(BiTree T,Status(* visit)(ElemType &e)) {//采用二叉链表存储结构,visit是对数据元素操作的应用函数 //后序遍历二叉树T的非递归算法,对每个数据元素调用函数visit //非递归算法 SqStack S;InitStack(S);BiTree p=T,pre=NULL; while(p||!StackEmpty(S)){ while(p){//根指针进栈,遍历左子树 Push(S,(SElemType)p); p=p->lchild; }//while GetTop(S,(SElemType&)p); //如果p没有右孩子或者其右孩子刚刚被访问过 if(p->rchild==NULL||p->rchild==pre) { if(!visit(p->data))return ERROR; Pop(S,(SElemType &)p); pre=p; p=NULL; }//if else p=p->rchild; }//while return OK; }//postOrderTraverse void printBiTree(BiTree T,int n) {//将二叉树以树的结构输出,首次调用n为0 //模式1,实线为左子树,虚线为右子树 int i; if(T){ printf("%c\n",T->data); if(T->lchild){ for(i=0;i<n;i++){ if(lmark[i]==0)printf("┆ "); else printf(" "); }//for if(T->rchild){ printf("├─"); lmark[n]=0; }//if(T->rchild) else{ printf("└─"); lmark[n]=1; }//else printBiTree(T->lchild,n+1); }//if(T->lchild) if(T->rchild){ for(i=0;i<n;i++){ if(lmark[i]==0)printf("┆ "); else printf(" "); }//for printf("└┄"); lmark[n]=1; printBiTree(T->rchild,n+1); }//if(T->rchild) } }//printBiTree void printBiTree2(BiTree T,int n) {//将二叉树以树的结构输出,首次调用n为0 //模式2,先左子树后右子树,没有显示空 int i; if(n>MAXLAYER)return; if(T) { printf("%c\n",T->data); if(T->rchild||T->lchild){ for(i=0;i<n;i++){ if(lmark[i]==0)printf("│ "); else printf(" "); }//for printf("├─"); lmark[n]=0; printBiTree2(T->lchild,n+1); //目的是为左右子树清晰 for(i=0;i<n;i++){ if(lmark[i]==0)printf("│ "); else printf(" "); }//for printf("└┄"); lmark[n]=1; printBiTree2(T->rchild,n+1); }//if lmark[n]=1; }//if(T) else printf("空\n"); }//printBiTree2 //------------------—栈的顺序存储结构 基本操作的实现 结束-------------------- //------------------------------命令及界面 函数 定义 开始----------------------- char *precmd="HhCcOoTtUuVvWwLlXxYyZzAaRrEe\033"; int isCmd(char cmd) {//判断是否为命令 int i; for(i=0;precmd[i]!='\0';i++) { if(precmd[i]==cmd)return 1; } return 0; } void Pause() {//按任意键继续 printf("\n按任意键继续……\n"); getch(); }//Pause void Goodbye(BiTree &t) {//显示结束画面,并结束程序 DestroyTree(t);//用完销毁 system("cls"); printf("\n\n\n\n\t\t\tGoodbye\n\n"); printf("\t\t\t\t******CopyLeft#WrittenBy huaying1988.com******\n\n"); Pause();//按任意键继续 exit(0); }//Goodbye void Help() {//命令帮助 printf("命令说明:\n\ h/H(help)----------命令帮助\n\ c/C(create)--------建立/重建二叉树\n\ o/O(output)--------以模式一输出二叉树(实线为左子树,虚线为右子树)\n\ t/T(type)----------以模式二输出二叉树(先左子树后右子树,没有显示空)\n\ u/U----------------先序遍历二叉树(递归算法)\n\ v/V----------------中序遍历二叉树(递归算法)\n\ w/W----------------后序遍历二叉树(递归算法)\n\ r/R(result)--------输出二叉树同时显示四种遍历结果\n\ x/X----------------先序遍历二叉树(非递归算法)\n\ y/Y----------------中序遍历二叉树(非递归算法)\n\ z/Z----------------后序遍历二叉树(非递归算法)\n\ l/L(level)---------层次遍历二叉树\n\ a/A(all)-----------输出二叉树同时显示四种遍历结果\n\ e/E(exit)----------退出\n"); }//Help void OpenScreen() {//开始画面 system("color f0"); system("title 二叉树遍历演示程序 WrittenBy huaying1988.com"); printf("\n\n\n\t\t\t二叉树遍历演示程序\n"); printf("\t\t\t**学院 **07-*\n"); printf("\t\t\t ***** 学号:**********\n"); printf("\n\t说明:\n\ 演示二叉树的先序,中序,后序,层次的递归与非递归遍历\n"); printf("\t\t\t\t******CopyLeft#WrittenBy huaying1988.com******\n\n"); Pause(); system("cls"); Help(); }//OpenScreen void CMDtran(char c,BiTree &t) {//解释命令并执行 putch('\n'); //char o; switch(c) { case 'H'://pass through case 'h'://命令帮助 Help(); break; case 'C'://pass through case 'c'://建立重建二叉树 if(t){ printf("二叉树已存在,是否重建?(y/*)\n"); //do{o=getch()}while(o!='y'||o!='n'); if(getch()=='y') { DestroyTree(t); printf("构建一棵二叉树(请依提示依次输入节点):\n"); CreateBiTree(t,0); }//if(getch) else{ printf("用户撤销重建\n"); }//else }//if(t) else{ printf("构建一棵二叉树(请依提示依次输入节点):\n"); CreateBiTree(t,0); }//else break; case 'o'://pass through case 'O'://以模式一输出二叉树(实线为左子树,虚线为右子树) printf("以模式1输出二叉树,实线为左子树,虚线为右子树:\n"); printBiTree(t,0); break; case 't'://pass through case 'T'://以模式二输出二叉树(先左子树后右子树,没有显示空) printf("以模式2输出二叉树,先左子树后右子树,没有显示空:\n"); printBiTree2(t,0); break; case 'u'://pass through case 'U'://先序遍历二叉树(递归算法) printf("先序遍历二叉树(递归):\n"); PreOrderTraverse(t,output); putch('\n'); break; case 'v'://pass through case 'V'://中序遍历二叉树(递归算法) printf("中序遍历二叉树(递归):\n"); InOrderTraverse(t,output); putch('\n'); break; case 'W'://pass through case 'w'://后序遍历二叉树(递归算法) printf("后续遍历二叉树(递归):\n"); PostOrderTraverse(t,output); putch('\n'); break; case 'l'://pass through case 'L'://层次遍历二叉树 printf("层次遍历二叉树:\n"); LevelOrderTraverse(t,output); putch('\n'); break; case 'x'://pass through case 'X'://先序遍历二叉树(非递归算法) printf("先序遍历二叉树(非递归):\n"); preOrderTraverse(t,output); putch('\n'); break; case 'Y'://pass through case 'y'://中序遍历二叉树(非递归算法) printf("中序遍历二叉树(非递归):\n"); inOrderTraverse(t,output); putch('\n'); break; case 'z'://pass through case 'Z'://后序遍历二叉树(非递归算法) printf("后续遍历二叉树(非递归):\n"); postOrderTraverse(t,output); putch('\n'); break; case 'a'://pass through case 'A'://输出二叉树同时显示四种遍历结果 printf("输出二叉树:\n"); printBiTree2(t,0); printf("层次遍历二叉树:\n"); LevelOrderTraverse(t,output); putch('\n'); printf("先序遍历二叉树(非递归):\n"); preOrderTraverse(t,output); putch('\n'); printf("中序遍历二叉树(非递归):\n"); inOrderTraverse(t,output); putch('\n'); printf("后续遍历二叉树(非递归):\n"); postOrderTraverse(t,output); putch('\n'); break; case 'r'://pass through case 'R'://输出二叉树同时显示四种遍历结果 printf("输出二叉树:\n"); printBiTree(t,0); printf("层次遍历二叉树:\n"); LevelOrderTraverse(t,output); putch('\n'); printf("先序遍历二叉树(递归):\n"); PreOrderTraverse(t,output); putch('\n'); printf("中序遍历二叉树(递归):\n"); InOrderTraverse(t,output); putch('\n'); printf("后续遍历二叉树(递归):\n"); PostOrderTraverse(t,output); putch('\n'); break; case 27://pass through case 'e'://pass through case 'E'://退出 Goodbye(t); break; default://其他输入 printf("不能识别的命令\n"); }//switchn cmd; }//CMDtran char inCMD() {//命令输入函数 char cmd; printf("h-help,e-exit|cmd>"); do{cmd=getch();}while(!isCmd(cmd)); putch(cmd); return cmd; } //-----------------------------命令及界面 函数 定义 结束----------------------- //----------------------------主函数 开始--------------------------------------- int main(){ BiTree t=NULL; char cmd; // printf("%d\n",'-'); OpenScreen(); do{ printf("\n"); cmd=inCMD(); CMDtran(cmd,t); }while(1); // Goodbye(t); }//main //----------------------------主函数 结束--------------------------------------- ``` ## 四、测试数据及结果分析: ### 运行界面: ![运行界面](BiTree.png "运行界面") ### 测试数据1: 在命令提示符”h-help,x-exit|cmd>”下输入“c”,构建二叉树,依次输入ABCφφDEφGφφFφφφ,其中φ表示空格,依次显示二叉树如下: ``` 构建一棵二叉树(请依提示依次输入节点): A ├─B │ ├─C │ │ ├─无 │ │ └─无 │ └─D │ ├─E │ │ ├─无 │ │ └─G │ │ ├─无 │ │ └─无 │ └─F │ ├─无 │ └─无 └─无 输入O或T可以查看输入的二叉树,下面为输入T后显示的二叉树: 以模式2输出二叉树,先左子树后右子树,没有显示空: A ├─B │ ├─C │ └┄D │ ├─E │ │ ├─空 │ │ └┄G │ └┄F └┄空 输入R可以查看二叉树以及所有遍历结果 输出二叉树: A └─B ├─C └┄D ├─E ┆ └┄G └┄F 层次遍历二叉树: ABCDEFG 先序遍历二叉树(递归): ABCDEGF 中序遍历二叉树(递归): CBEGDFA 后续遍历二叉树(递归): CGEFDBA ``` 结果正确。 ### 测试数据2: 构建如下二叉树:abcdefφφgφφφφhijφklφφφφφmnoφpφqφrφφsφtuφφφvφwφφ,得: ``` 构建一棵二叉树(请依提示依次输入节点): a ├─b │ ├─c │ │ ├─d │ │ │ ├─e │ │ │ │ ├─f │ │ │ │ │ ├─无 │ │ │ │ │ └─无 │ │ │ │ └─g │ │ │ │ ├─无 │ │ │ │ └─无 │ │ │ └─无 │ │ └─无 │ └─h │ ├─i │ │ ├─j │ │ │ ├─无 │ │ │ └─k │ │ │ ├─l │ │ │ │ ├─无 │ │ │ │ └─无 │ │ │ └─无 │ │ └─无 │ └─无 └─m ├─n │ ├─o │ │ ├─无 │ │ └─p │ │ ├─无 │ │ └─q │ │ ├─无 │ │ └─r │ │ ├─无 │ │ └─无 │ └─s │ ├─无 │ └─t │ ├─u │ │ ├─无 │ │ └─无 │ └─无 └─v ├─无 └─w ├─无 └─无 输入“r”得: 输出二叉树: a ├─b ┆ ├─c ┆ ┆ └─d ┆ ┆ └─e ┆ ┆ ├─f ┆ ┆ └┄g ┆ └┄h ┆ └─i ┆ └─j ┆ └┄k ┆ └─l └┄m ├─n ┆ ├─o ┆ ┆ └┄p ┆ ┆ └┄q ┆ ┆ └┄r ┆ └┄s ┆ └┄t ┆ └─u └┄v └┄w 层次遍历二叉树: abmchnvdioswejptfgkqulr 先序遍历二叉树(递归): abcdefghijklmnopqrstuvw 中序遍历二叉树(递归): fegdcbjlkihaopqrnsutmvw 后续遍历二叉树(递归): fgedclkjihbrqpoutsnwvma ``` 经检验结果正确。 **注:转发请注明出处,以免老师误以为本人抄袭……**


发表评论

必填,公开,这样称呼起来方便~

必填,不会被公开,不必担心~

http://

非必填,公开,目的是方便增进友好访问~

必填,请输入下方图片中的字母或数字,以证明你是人类

看不清楚
必填,最好不要超过500个字符
     ↑返回顶端↑