数据结构实验五

南昌航空大学实验报告

0 21    5   27 

 

课程名称:     数据结构实验       实验名称:        线性表的链式存储结构   

班级:               姓名:                同组人:                        

指导教师评定:                                      签名:                  

 

必做1

一、 需求分析

题目:设计并验证如下算法:按后序序列建立二叉树的二叉链表结构,求其单分支结点数目,双分支结点数目,并交换该二叉树。

1、在本次实验中,首先,从键盘输入,按照输入字符构建二叉树,在进行二叉树交换与先序递归遍历并输出,输出单分支结点数目与双分支结点数目。

2. 演示程序以用户和计算机对话的方式进行,即在计算机终端上显示“提示信息”之后,按照提示信息输入。

3. 程序执行的命令包括:

(1) 输入二叉树信息

(2) 后序递归构建二叉树

(3) 交换二叉树

(4) 交换前先序递归遍历

(5) 交换后先序递归遍历

4. 测试数据

输入:

##b##d#ca

单分支节点数目:1,双分支节点数目:1

先序遍历:

a b c d

交换后先序遍历为:

a c d b

二、 概要设计

1. 抽象数据类型定义

为实现上述程序功能,需要一个抽象数据类型:图。

ADT Graph{

基本操作:

InitBiTree(BiTree *BT)

操作结果:二叉树初始化

CreateBiTree(BiTree *BT,char ch[],int &count1,int &count2,int &count3)

操作结果:后序递归建立二叉树

Exchange(BiTree *BT)

操作结果:交换二叉树

PreOrder(BiTree BT)

操作结果:先序遍历二叉树

2.程序模块

1)主程序流程

void main{

   初始化两个二叉树;

输入;

后序遍历创建二叉树;

输出单分支,双分支结点数目;

先序遍历二叉树;

交换二叉树;

先序遍历交换后的二叉树;

}

(2)二叉树初始化;

(3)后序遍历建二叉树;

(4)交换二叉树;

(5)先序遍历二叉树;

    3.程序结构图

各模块之间的调用关系如图所示。

 

1 模块之间调用关系图

三、 详细设计

1.数据类型及结构体

typedef int Status;

typedef char TElemType;

typedef struct BiTNode{

TElemType data;

struct BiTNode *lchild,*rchild;

}BiTNode,*BiTree;

 

typedef BiTree SElemType;

typedef BiTree QElemType;

Status InitBiTree(BiTree *BT){/*构造空二叉树*/

Status CreateBiTree(BiTree *BT,char ch[],int &count1,int &count2,int &count3){/*后序递归建立二叉树*/

Status Exchange(BiTree *BT){/*交换二叉树*/

Status PreOrder(BiTree BT){/*先序递归遍历*/

  1. 主函数

int main(){

BiTree BT,BT1;

InitBiTree(&BT);

InitBiTree(&BT1);

int count1=0,count2=0,count3=0;

printf("请输入:\n");

TElemType ch1[100],ch2[100];

scanf("%s",&ch1);

int i=0;

int k=strlen(ch1);

for(int j=0,i=k-1;j<k;j++,i--)

{

ch2[j]=ch1[i];

}

CreateBiTree(&BT,ch2,count1,count2,count3);/*创建二叉树,返回根节点BT*/

printf("单分支结点数目:%d,双分支结点数目:%d\n",count2,count1);

printf("先序遍历为:\n");

PreOrder(BT);

printf("\n");

Exchange(&BT);

printf("交换后先序遍历为:\n");

PreOrder(BT);

return 0;

}

四、 调试分析

1. 第一次为了得到单分支与双分支结点数目采用了全局变量,改正后采用传地址来达到记录数据的目的:CreateBiTree(&BT,ch2,count1,count2,count3)

2.后序遍历建树最开始没思路,后来将输入字符串颠倒借助先序遍历建数(先序建树时先建右孩子在建左孩子)来实现。

3.整体代码的时间复杂度为O(n),每种操作对于每个结点而言都只遍历了一次,

五、 用户手册

1. 本程序的运行环境为DOS操作系统,执行文件为:main.exe

2. 进入演示程序后即显示文本方式的用户界面。

3. 程序运行后,按照提示信息输入后序遍历二叉树的结果

4. 建树后输出先序遍历的结果,单分支双分支结点数目,先序遍历交换左右孩子后树的结果。

六、 测试结果

测试结果

输入:

##b##d#ca

单分支节点数目:1,双分支节点数目:1

先序遍历:

a b c d

交换后先序遍历为:

a c d b

 

七、 附录

源代码:

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <string.h>

#define OK 1

#define ERROR 0

typedef int Status;

typedef char TElemType;

typedef struct BiTNode{

TElemType data;

struct BiTNode *lchild,*rchild;

}BiTNode,*BiTree;

 

typedef BiTree SElemType;

typedef BiTree QElemType;

 

 

Status InitBiTree(BiTree *BT){/*构造空二叉树*/

*BT=NULL;

}

 

Status CreateBiTree(BiTree *BT,char ch[],int &count1,int &count2,int &count3){/*后序递归建立二叉树*/

 

if(ch[count3]=='#'){

*BT=NULL;

count3++;

}

else{

*BT=(BiTree)malloc(sizeof(BiTree));

int k=ch[count3];

count3++;

CreateBiTree(&((*BT)->rchild),ch,count1,count2,count3);

CreateBiTree(&((*BT)->lchild),ch,count1,count2,count3);

(*BT)->data = k;

if((*BT)->lchild!=NULL&&(*BT)->rchild!=NULL)

count1++;

if(((*BT)->lchild!=NULL&&(*BT)->rchild==NULL)||((*BT)->lchild==NULL&&(*BT)->rchild!=NULL))

count2++;

   }

}

 

Status Exchange(BiTree *BT){/*交换二叉树*/

if(*BT){

BiTree p;

p = (*BT)->lchild;

(*BT)->lchild = (*BT)->rchild;

(*BT)->rchild = p;

Exchange(&(*BT)->lchild);

Exchange(&(*BT)->rchild);

}

}

 

Status PreOrder(BiTree BT){/*先序递归遍历*/

if(BT){

if(!(BT->data))

   return ERROR;

printf("%c ",BT->data);

PreOrder(BT->lchild);

PreOrder(BT->rchild);

return OK;

}

}

 

int main(){

BiTree BT,BT1;

InitBiTree(&BT);

InitBiTree(&BT1);

int count1=0,count2=0,count3=0;

printf("请输入:\n");

TElemType ch1[100],ch2[100];

scanf("%s",&ch1);

int i=0;

int k=strlen(ch1);

for(int j=0,i=k-1;j<k;j++,i--)

{

ch2[j]=ch1[i];

}

CreateBiTree(&BT,ch2,count1,count2,count3);/*创建二叉树,返回根节点BT*/

printf("单分支结点数目:%d,双分支结点数目:%d\n",count2,count1);

printf("先序遍历为:\n");

PreOrder(BT);

printf("\n");

Exchange(&BT);

printf("交换后先序遍历为:\n");

PreOrder(BT);

return 0;

}

 

 

 

 

 

 

 

 

 

 

必做2

一、 需求分析

题目:设计并验证如下算法:输入一棵二叉树的广义表形式,建立该二叉树的二叉链表结构,并求其总结点数目。

1、在本次实验中,首先,从键盘输入二叉树广义表形式,按照输入字符构建二叉树,输出二叉树的先序遍历以及总结点数目。

2. 演示程序以用户和计算机对话的方式进行,即在计算机终端上显示“提示信息”之后,按照提示信息输入。

3. 程序执行的命令包括:

(1) 输入二叉树信息

(2) 构建二叉树;

(3) 输出总结点数目;

(4) 先序遍历二叉树

4. 测试数据

输入:

C(E,(I,J),F(,G(K,H))#

总结点数目为:8

输出先序遍历:

C E I J F G K H

二、 概要设计

1. 抽象数据类型定义

为实现上述程序功能,需要一个抽象数据类型:图。

ADT Graph{

基本操作:

PreOrder(BiTree BT)

操作结果:输出先序递归遍历二叉树

 CreatTree(BiTree & BT)

操作结果:建立二叉树

2.程序模块

1)主程序流程

void main{

   初始化二叉树;

创建二叉树;

先序遍历二叉树;

}

2)二叉树初始化

3)建二叉树

4)先序遍历二叉树

    3.程序结构图

各模块之间的调用关系如图所示。

 

1 模块之间调用关系图

三、 详细设计

1.数据类型及结构体

typedef int Status;

typedef char TElemType;

 

 

typedef struct BiTNode{

TElemType data;

struct BiTNode *lchild,*rchild;

}BiTNode,*BiTree;

 

Status PreOrder(BiTree BT)/*先序递归遍历*/

 

 

Status CreatTree(BiTree & BT)/*建立二叉树*/

 

2.主函数

int main(){

BiTree BT;

printf("请输入:\n");

CreatTree(BT);

printf("输出先序序列:\n");

PreOrder(BT);

return 0;

}

四、 调试分析

1. 第一次建树用了for循环发现很混乱,便改用switch语句,使得代码更加清楚简洁

2.第一次入队列出队列的条件没搞清楚,什么时候该不该进队列,改进后:switch(a[i])

     {

    case '(':

            rear++;

            A[rear] = p;

            flag = 1;

            break;

    case ')':

            rear--;

            break;

    case ',':

        flag = 0;

break;

    default:

     p = (BiTNode *)malloc(sizeof(BiTNode));

         p->data = a[i];

         p->lchild = p->rchild = NULL;

         if(BT==NULL)

         BT=p;

         else

        {

     if ( flag == 1)

         A[rear]->lchild = p;

          else

     A[rear]->rchild = p;

         }

     }

3.整体代码的时间复杂度为O(n),每种操作对于每个结点而言都只遍历了一次,

五、 用户手册

1. 本程序的运行环境为DOS操作系统,执行文件为:main.exe

2. 进入演示程序后即显示文本方式的用户界面。

3. 程序运行后,按照提示信息输入二叉树的顺序表形式

4. 建树后输出先序遍历的结果,输出总结点数目。

六、 测试结果

测试结果

输入:

C(E,(I,J),F(,G(K,H))#

总结点数目为:8

输出先序遍历:

C E I J F G K H

七、 附录

源代码:

#include<stdio.h>

#include<stdlib.h>

#define STACK_SIZE 100

typedef int Status;

typedef char TElemType;

 

 

typedef struct BiTNode{

TElemType data;

struct BiTNode *lchild,*rchild;

}BiTNode,*BiTree;

 

Status PreOrder(BiTree BT){/*先序递归遍历*/

if(BT){

printf("%c ",BT->data);

PreOrder(BT->lchild);

PreOrder(BT->rchild);

}

}

 

Status CreatTree(BiTree & BT){

TElemType a[STACK_SIZE];

scanf("%s",a);

BiTree p;

    BiTree A[100];

    int rear = -1;

    BT=NULL;

    int flag=0;//1指左,0指右

    int i=0,j=0;

    while(a[i]!='#')

    {

    if(a[i]!=','&&a[i]!='('&&a[i]!=')')

    j++;

     switch(a[i])

     {

    case '(':

            rear++;

            A[rear] = p;

            flag = 1;

            break;

    case ')':

            rear--;

            break;

    case ',':

        flag = 0;

break;

    default:

     p = (BiTNode *)malloc(sizeof(BiTNode));

         p->data = a[i];

         p->lchild = p->rchild = NULL;

         if(BT==NULL)

         BT=p;

         else

        {

     if ( flag == 1)

         A[rear]->lchild = p;

          else

     A[rear]->rchild = p;

         }

     }

     i++;

    }

    printf("总结点数目为:%d\n",j);

}

 

int main(){

BiTree BT;

printf("请输入:\n");

CreatTree(BT);

printf("输出先序序列:\n");

PreOrder(BT);

return 0;

}

posted @ 2022-03-14 23:17  安良  阅读(964)  评论(0编辑  收藏  举报