数据结构试验报告---二叉树的生成,遍历二叉树(递归前中后,非递归前中后)

上机实验习题
上机实验要求及规范
C程序设计具有比较强的理论性,同时也具有较强的可应用性和实践性。在上机实验是一个重要的教学环节。具体实习步骤如下:
1.问题分析与系统结构设计
充分地分析和理解问题本身,弄清要求做什么(而不是怎么做),限制条件是什么。按照以数据结构为中心的原则划分模块,搞清数据的逻辑结构(是线性表还是树、图?),确定数据的存储结构(是顺序结构还是链表结构?)。然后设计有关操作的函数。在每个函数模块中,要综合考虑系统功能,使系统结构清晰、合理、简单和易于调试。最后写出每个模块的算法头和规格说明,列出模块之间的调用关系(可以用图表示),便完成了系统结构设计。
3.上机准备
熟悉高级语言用法,如C语言。熟悉机器(即操作系统),基本的常用命令。静态检查主要有两条路径,一是用一组测试数据手工执行程序(或分模块进行);二是通过阅读或给别人讲解自己的程序而深入全面地理解程序逻辑,在这个过程中再加入一些注释和断言。如果程序中逻辑概念清楚,后者将比前者有效。
4.上机调试程序
调试最好分块进行,自底向上,即先调试底层函数,必要时可以另写一个调用驱动程序,表面上的麻烦工作可以大大降低调试时所面临的复杂性,提高工作效率。
5.整理实习报告
在上机实开始之前要充分准备实验数据,在上机实践过程中要及时记录实验数据,在上机实践完成之后必须及时总结分析。写出实验报告。
一、实验报告的基本要求:
一般性、较小规模的上机实验题,必须遵循下列要求。养成良好的习惯。
(1)姓名 班级 学号 日期
(2)题目:内容叙述
(3)程序清单(带有必要的注释)
(4)调试报告:
实验者必须重视这一环节,否则等同于没有完成实验任务。这里可以体现个人特色、或创造性思维。具体内容包括:测试数据与运行记录;调试中遇到的主要问题,自己是如何解决的;经验和体会等。
二、实验习报告的提高要求:
阶段性、较大规模的上机实验题,应该遵循下列要求。养成科学的习惯。
(1)需求和规格说明
描述问题,简述题目要解决的问题是什么。规定软件做什么。原题条件不足时补全。
(2)设计
a.设计思想:存储结构(题目中限定的要描述);主要算法基本思想。
b.设计表示:每个函数的头和规格说明;列出每个函数所调用和被调用的函数,也可以通过调用关系图表达。
c.实现注释:各项功能的实现程度、在完成基本要求的基础上还有什么功能。
(3)用户手册:即使用说明。
(4)调试报告:调试过程中遇到的主要问题是如何解决的;设计的回顾、讨论和分析;时间复杂度、空间复杂度分析;改进设想;经验和体会等。

编制部门:国土资源学院 编制人: 审核人: 编制日期:2017年5月3日
项目编号 No. C001
项目名称 数据结构
训练对象 GIS 2015级7、8
学时 4
课程名称 数据结构实验
教 材 数据结构(C语言版)

目的
Objective 1.学会用算法来进行编程。
第一题
请用两次课的时间完善下列程序的功能函数:

void CreateBiTree(BiTree &T); //生成一个二叉树
void PreOrder(BiTree); //递归先序遍历二叉树
void InOrder(BiTree); //递归中序遍历二叉树
void PostOrder(BiTree); //递归后序遍历二叉树
void InOrderTraverse(BiTree T); //非递归中序遍历二叉树
void PreOrder_Nonrecursive(BiTree T);//非递归先序遍历二叉树
void LeverTraverse(BiTree T);//非递归层序遍历二叉树
第二题
请理解中序遍历线索二叉树的线索化原理,对一颗二叉树进行中序线索化,并用中序遍历的方式输出来。

该二叉树:ABC DE G F .(点号不算)
第一题:
程序代码如下:

#include  
#include  
#include  
using namespace std;  

//二叉树结点 
typedef struct BiTNode{  
    //数据 
    char data;  
    //左右孩子指针 
    struct BiTNode *lchild,*rchild;  
}BiTNode,*BiTree;  
  
//按先序序列创建二叉树 
int CreateBiTree(BiTree &T);    //生成一个二叉树
void PreOrder(BiTree);          //递归先序遍历二叉树
void InOrder(BiTree);           //递归中序遍历二叉树
void PostOrder(BiTree);         //递归后序遍历二叉树
void InOrderTraverse(BiTree T); //非递归中序遍历二叉树
void PreOrder_Nonrecursive(BiTree T);//非递归先序遍历二叉树
void LeverTraverse(BiTree T);//非递归层序遍历二叉树

int CreateBiTree(BiTree &T){  
    char data;  
    //按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树 
    scanf("%c",&data);  
    if(data == '#'){  
        T = NULL;  
    }  
    else{  
        T = (BiTree)malloc(sizeof(BiTNode));  
        //生成根结点 
        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);  
    }  
}  
/* 先序遍历(非递归) 
   思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
*/  
void PreOrder2(BiTree T){  
    stack stack;  
    //p是遍历指针 
    BiTree p = T;  
    //栈不空或者p不空时循环 
    while(p || !stack.empty()){  
        if(p != NULL){  
            //存入栈中 
            stack.push(p);  
            //访问根节点 
            printf("%c ",p->data);  
            //遍历左子树 
            p = p->lchild;  
        }  
        else{  
            //退栈 
            p = stack.top();  
            stack.pop();  
            //访问右子树 
            p = p->rchild;  
        }  
    }//while  
}  
/* 中序遍历(非递归) 
   思路:T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
         先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。
*/  
void InOrder2(BiTree T){  
    stack stack;  
    //p是遍历指针 
    BiTree p = T;  
    //栈不空或者p不空时循环 
    while(p || !stack.empty()){  
        if(p != NULL){  
            //存入栈中 
            stack.push(p);  
            //遍历左子树 
            p = p->lchild;  
        }  
        else{  
            //退栈,访问根节点 
            p = stack.top();  
            printf("%c ",p->data);  
            stack.pop();  
            //访问右子树 
            p = p->rchild;  
        }  
    }//while  
}  
//后序遍历(非递归)  
typedef struct BiTNodePost{  
    BiTree biTree;  
    char tag;  
}BiTNodePost,*BiTreePost;   
void PostOrder2(BiTree T){  
    stack stack;  
    //p是遍历指针 
    BiTree p = T;  
    BiTreePost BT;  
    //栈不空或者p不空时循环 
    while(p != NULL || !stack.empty()){  
        //遍历左子树 
        while(p != NULL){  
            BT = (BiTreePost)malloc(sizeof(BiTNodePost));  
            BT->biTree = p;  
            //访问过左子树 
            BT->tag = 'L';  
            stack.push(BT);  
            p = p->lchild;  
        }  
        //左右子树访问完毕访问根节点 
        while(!stack.empty() && (stack.top())->tag == 'R'){  
            BT = stack.top();  
            //退栈 
            stack.pop();  
            printf("%c ",BT->biTree->data);  
        }  
        //遍历右子树 
        if(!stack.empty()){  
            BT = stack.top();  
            //访问过右子树 
            BT->tag = 'R';  
            p = BT->biTree;  
            p = p->rchild;  
        }  
    }//while  
}  
//层次遍历 
void LevelOrder(BiTree T){  
    BiTree p = T;  
    //队列 
    queue queue;  
    //根节点入队 
    queue.push(p);  
    //队列不空循环 
    while(!queue.empty()){  
        //对头元素出队 
        p = queue.front();  
        //访问p指向的结点 
        printf("%c ",p->data);  
        //退出队列 
        queue.pop();  
        //左子树不空,将左子树入队 
        if(p->lchild != NULL){  
            queue.push(p->lchild);  
        }  
        //右子树不空,将右子树入队 
        if(p->rchild != NULL){  
            queue.push(p->rchild);  
        }  
    }  
}  
int main()  
{  
    BiTree T;  
    CreateBiTree(T);  
    printf("先序遍历:\n");  
    PreOrder(T);  
    printf("\n");  
    printf("先序遍历(非递归):\n");  
    PreOrder2(T);  
    printf("\n");  
    printf("中序遍历:\n");  
    InOrder(T);  
    printf("\n");  
    printf("中序遍历(非递归):\n");  
    InOrder2(T);  
    printf("\n");  
    printf("后序遍历:\n");  
    PostOrder(T);  
    printf("\n");  
    printf("后序遍历(非递归):\n");  
    PostOrder2(T);  
    printf("\n");  
    printf("层次遍历:\n");  
    LevelOrder(T);  
    printf("\n");  
    return 0;  
}

实验二
请理解中序遍历线索二叉树的线索化原理,对一颗二叉树进行中序线索化,并用中序遍历的方式输出来。

该二叉树:ABC DE G F .(点号不算)

程序代码如下:
//算法5.9 遍历中序线索二叉树

#include   
  
//二叉树的二叉线索类型存储表示  
typedef struct BiThrNode  
{                 
    char data;                          //结点数据域  
    struct BiThrNode *lchild,*rchild;   //左右孩子指针  
    int LTag,RTag;  
}BiThrNode,*BiThrTree;  
  
//全局变量pre  
BiThrNode *pre=new BiThrNode;  
  
//用算法5.3建立二叉链表  
void CreateBiTree(BiThrTree &T)  
{     
    //按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T  
    char ch;  
    scanf("%c",&ch);  
    if(ch=='#')  T=NULL;            //递归结束,建空树  
    else  
    {                             
        T=new BiThrNode;  
        T->data=ch;                  //生成根结点  
        CreateBiTree(T->lchild); //递归创建左子树  
        CreateBiTree(T->rchild); //递归创建右子树  
    }                               //else  
}                                   //CreateBiTree  
  
//用算法5.7以结点P为根的子树中序线索化  
void InThreading(BiThrTree p)  
{  
    //pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索  
    if(p)  
    {  
        InThreading(p->lchild);                      //左子树递归线索化  
        if(!p->lchild)  
        {                                               //p的左孩子为空  
            p->LTag=1;                                   //给p加上左线索  
            p->lchild=pre;                               //p的左孩子指针指向pre(前驱)  
        }   
        else  
            p->LTag=0;  
        if(!pre->rchild)  
        {                                               //pre的右孩子为空  
            pre->RTag=1;                                 //给pre加上右线索  
            pre->rchild=p;                               //pre的右孩子指针指向p(后继)  
        }  
        else  
            pre->RTag=0;  
        pre=p;                                          //保持pre指向p的前驱  
        InThreading(p->rchild);                          //右子树递归线索化  
    }  
}//InThreading  
  
//用算法5.8带头结点的中序线索化  
void InOrderThreading (BiThrTree &Thrt,BiThrTree T)  
{  
    //中序遍历二叉树T,并将其中序线索化,Thrt指向头结点  
    Thrt=new BiThrNode;                 //建头结点  
    Thrt->LTag=0;                        //头结点有左孩子,若树非空,则其左孩子为树根  
    Thrt->RTag=1;                    //头结点的右孩子指针为右线索  
    Thrt->rchild=Thrt;                   //初始化时右指针指向自己  
    if(!T)  Thrt->lchild=Thrt;       //若树为空,则左指针也指向自己  
    else  
    {  
      Thrt->lchild=T;  pre=Thrt;         //头结点的左孩子指向根,pre初值指向头结点  
      InThreading(T);                   //调用算法5.7,对以T为根的二叉树进行中序线索化  
      pre->rchild=Thrt;                  //算法5.7结束后,pre为最右结点,pre的右线索指向头结点  
      pre->RTag=1;                  
      Thrt->rchild=pre;              //头结点的右线索指向pre  
    }  
}                 
void InOrderTraverse_Thr(BiThrTree T)  
{   BiThrNode *p=new BiThrNode;  
    p=T->lchild;  
    while(p!=T)  
    {  
        while(p->LTag==0)  
            p=p->lchild;  
        printf("%c",p->data);  
        while(p->RTag==1&&p->rchild!=T){  
                p=p->rchild;  
                printf("%c",p->data);  
        }  
        p=p->rchild;  
          
    }  
}  
int main()  
{  
    pre->RTag=1;  
    pre->rchild=NULL;  
    BiThrTree tree,Thrt;  
    printf("请输入建立二叉链表的序列:\n");  
    CreateBiTree(tree);  
    InOrderThreading(Thrt,tree);  
    printf("中序遍历线索二叉树的结果为:\n");  
    InOrderTraverse_Thr(Thrt);  
    printf("\n");  
    return 0;  
}

心得体会:

你可能感兴趣的:(数据结构学习)