# 数据结构课程设计大曝光(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
//----------------------------主函数 结束---------------------------------------
```
## 四、测试数据及结果分析:
### 运行界面:

### 测试数据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
```
经检验结果正确。
**注:转发请注明出处,以免老师误以为本人抄袭……**