您好,欢迎来到意榕旅游网。
搜索
您的当前位置:首页数据结构实验报告

数据结构实验报告

来源:意榕旅游网


实验题目 二叉树的基本操作

一、 实验目的与要求

实验目的:

1、实现二叉树的各种运算。

2、实现二叉树的各种遍历。

实验要求:

完成课本实验题7.1、实验题7.2要求实现的各项功能。

二、 实验方案

实验7-1

//文件名:algo7-1.cpp

#include

#include

#define MaxSize 100

typedef char ElemType;

typeder struct node

{ ElemType data;

struct node*lchild;

struct node*rchild;

}BTNode;

void CreateBTNode(BTNode *&b,char *str)

{ BTNode *St[MaxSize],*p=NULL;

int top=-1,k,j=0;

char ch;

b=NULL;

ch=str[j];

while(ch!='\\0')

{ switch(ch)

{

case '(':top++;St[top]=p;k=1;break;

case')':top--;break;

case',':k=2;break;

default:p=(BTNode*)malloc(sizeof(BTNode));

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

if(b==NULL)

b=p;

else

{ switch(k)

{

case1:St[top]->lchild=p;break;

case2:St[top]->rchild=p;break;

}

}

}

j++;

ch=str[j];

}

}

BTNode*FindNode(BTNode*b,ElemType x)

{ BTNode*p;

if(b==NULL)

return NULL;

else if(b->data==x)

return b;

else

{ p=FindNode(b->lchild,x);

if(p!=NULL)

return b;

else

return FindNode(b->rchild,x);

}

}

BTNode*LchildNode(BTNode *p)

{

return p->lchild;

}

BTNode*RchildNode(BTNode *p)

{

return p->rchild;

}

int BTNodeDepth(BTNode *b)

{ int lchilddep,rchilddep;

if (b==NULL)

return(0);

else

{ lchilddep=BTNodeDepth(b->lchild);

rchilddep=BTNodeDepth(b->rchild);

return (lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1);

}

}

void DispBTNode(BTNode*b)

{ if(b!=NULL)

{ printf(\"%c\",b->data);

if(b->lchild!=NULL||b->rchild!=NULL)

{ printf(\"(\");

DispBTNode(b->lchild);

if(b->rchild!=NULL) printf(\);

DispBTNode(b->rchild);

printf(\")\");

}

}

}

int BTWidth(BTNode*b)

{struct

{ int lno;

BTNode*p;

}Qu[MaxSize];

int front,rear;

int lnum,max,i,n;

front=rear=0;

if(b!=NULL)

{ rear++;

Qu[rear].p=b;

Qu[rear].lno=1;

while(rear!=front)

{ front++;

b=Qu[front].p;

lnum=Qu[front].lno;

if(b->lchild!=NULL)

{ rear++;

Qu[rear].p=b->lchild;

Qu[rear].lno=lnum+1;

}

if(b->rchild!=NULL)

{ rear++;

Qu[rear].p=b->rchild;

Qu[rear].lno=lnum+1;

}

}

max=0;lnum=1;i=1;

while(i<=rear)

{ n=0;

while(i<=rear&&Qu[i].lno==lnum)

{

n++;i++;

}

lnum=Qu[i].lno;

if(n>max)max=n;

}

return max;

}

else

return 0;

}

int Nodes(BTNode*b)

{ int num1,num2;

if(b==NULL)

return 0;

else if(b->lchild==NULL&&b->rchild==NULL)

return 1;

else

{ num1=Nodes(b->lchild);

num2=Nodes(b->rchild);

return (num1+num2+1);

}

}

int LeafNodes(BTNode*b)

{ int num1,num2;

if(b==NULL)

return 0;

else if(b->lchild==NULL&&b->rchild==NULL)

return 1;

else

{ num1=LeafNodes(b->lchild);

num2=LeafNodes(b->rchild);

return(num1+num2);

}

}

void DestroyBTNode(BTNode*&b)

{ if(b!=NULL)

{ DestroyBTNode(b->lchild);

DestroyBTNode(b->rchild);

free(b);

}

}

//文件名:exp7-1.cpp:

#include

typedef char ElemType;

typeder struct node

{ ElemType data;

struct node*lchild;

struct node*rchild;

}BTNode;

extern void CreateBTNode(BTNode *&b,char *str);

extern BTNode*FindNode(BTNode*b,ElemType x);

extern BTNode*LchildNode(BTNode *p);

extern BTNode*RchildNode(BTNode *p);

extern int BTNodeDepth(BTNode *b);

extern void DispBTNode(BTNode*b);

extern int BTWidth(BTNode*b);

extern int Nodes(BTNode*b);

extern int LeafNodes(BTNode*b);

extern void DestroyBTNode(BTNode*&b);

void main()

{ BTNode *b,*p,*lp,*rp;

CreateBTNode(b,\"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))\");

printf(\"二叉树的基本运算如下:\\n\");

printf(\"(1)输出二叉树:\");DispBTNode(b);printf(\"\\n\");

printf(\"(2)H节点:\");

p=FindNode(b,'H');

if(p!=NULL)

{ lp=LchildNode(p);

if(lp!=NULL)

printf(\"左孩子为%c\",lp->data);

else

printf(\"无左孩子\");

rp=RchildNode(p);

if(rp!=NULL)

printf(\"右孩子为%c\",rp->data);

else

printf(\"无右孩子\");

}

printf(\"\\n\");

printf(\" (3)二叉树b的深度:%d\\n\",BTNodeDepth(b));

printf(\" (4)二叉树b的宽度:%d\\n\",BTWidth(b));

printf(\" (5)二叉树b的节点个数:%d\\n\",Nodes(b));

printf(\" (6)二叉树b的叶子节点个数:%d\\n\",LeafNodes(b));

printf(\" (7)释放二叉树b\\n\");

DestroyBTNode(b);

}

实验7-2

/*文件名:exp7-2.cpp*/

#include

#include

#define MaxSize 100

typedef char ElemType;

typedef struct node

{

ElemType data; /*数据元素*/

struct node *lchild; /*指向左孩子*/

struct node *rchild; /*指向右孩子*/

} BTNode;

extern void CreateBTNode(BTNode *&b,char *str);

extern void DispBTNode(BTNode *b);

void PreOrder(BTNode *b) /*先序遍历的递归算法*/

{

if (b!=NULL)

{

printf(\"%c \访问根结点*/

PreOrder(b->lchild); /*递归访问左子树*/

PreOrder(b->rchild); /*递归访问右子树*/

}

}

void PreOrder1(BTNode *b)

{

BTNode *p;

struct

{

BTNode *pt;

int tag;

} St[MaxSize];

int top=-1;

top++;

St[top].pt=b;St[top].tag=1;

while (top>-1) /*栈不空时循环*/

{

if (St[top].tag==1) /*不能直接访问的情况*/

{

p=St[top].pt;

top--;

if (p!=NULL)

{

top++; /*右孩子进栈*/

St[top].pt=p->rchild;

St[top].tag=1;

top++; /*左孩子进栈*/

St[top].pt=p->lchild;

St[top].tag=1;

top++; /*根结点进栈*/

St[top].pt=p;

St[top].tag=0;

}

}

if (St[top].tag==0) /*直接访问的情况*/

{

printf(\"%c \

top--;

}

}

}

void PreOrder2(BTNode *b)

{

BTNode *St[MaxSize],*p;

int top=-1;

if (b!=NULL)

{

top++; /*根结点入栈*/

St[top]=b;

while (top>-1) /*栈不为空时循环*/

{

p=St[top]; /*退栈并访问该结点*/

top--;

printf(\"%c \

if (p->rchild!=NULL) {

top++;

St[top]=p->rchild;

}

if (p->lchild!=NULL) {

top++;

St[top]=p->lchild;

}

}

printf(\"\\n\");

/*右孩子入栈*/

/*左孩子入栈*/

}

}

void InOrder(BTNode *b) /*中序遍历的递归算法*/

{

if (b!=NULL)

{

InOrder(b->lchild); /*递归访问左子树*/

printf(\"%c \访问根结点*/

InOrder(b->rchild); /*递归访问右子树*/

}

}

void InOrder1(BTNode *b)

{

BTNode *p;

struct

{

BTNode *pt;

int tag;

} St[MaxSize];

int top=-1;

top++;

St[top].pt=b;St[top].tag=1;

while (top>-1) /*栈不空时循环*/

{

if (St[top].tag==1) /*不能直接访问的情况*/

{

p=St[top].pt;

top--;

if (p!=NULL)

{

top++; /*右孩子进栈*/

St[top].pt=p->rchild;

St[top].tag=1;

top++; /*根结点进栈*/

St[top].pt=p;

St[top].tag=0;

top++; /*左孩子进栈*/

St[top].pt=p->lchild;

St[top].tag=1;

}

}

if (St[top].tag==0) /*直接访问的情况*/

{

printf(\"%c \

top--;

}

}

}

void InOrder2(BTNode *b)

{

BTNode *St[MaxSize],*p;

int top=-1;

if (b!=NULL)

{

p=b;

while (top>-1 || p!=NULL)

{

while (p!=NULL)

{

top++;

St[top]=p;

p=p->lchild;

}

if (top>-1)

{

p=St[top];

top--;

printf(\"%c \

p=p->rchild;

}

}

printf(\"\\n\");

}

}

void PostOrder(BTNode *b) /*后序遍历的递归算法*/

{

if (b!=NULL)

{

PostOrder(b->lchild); /*递归访问左子树*/

PostOrder(b->rchild); /*递归访问右子树*/

printf(\"%c \访问根结点*/

}

}

void PostOrder1(BTNode *b)

{

BTNode *p;

struct

{

BTNode *pt;

int tag;

} St[MaxSize];

int top=-1;

top++;

St[top].pt=b;St[top].tag=1;

while (top>-1) /*栈不空时循环*/

{

if (St[top].tag==1) /*不能直接访问的情况*/

{

p=St[top].pt;

top--;

if (p!=NULL)

{

top++; /*根结点进栈*/

St[top].pt=p;

St[top].tag=0;

top++; /*右孩子进栈*/

St[top].pt=p->rchild;

St[top].tag=1;

top++; /*左孩子进栈*/

St[top].pt=p->lchild;

St[top].tag=1;

}

}

if (St[top].tag==0) /*直接访问的情况*/

{

printf(\"%c \

top--;

}

}

}

void PostOrder2(BTNode *b)

{

BTNode *St[MaxSize];

BTNode *p;

int flag,top=-1; if (b!=NULL)

/*栈指针置初值*/

{

do

{

while (b!=NULL) /*将t的所有左结点入栈*/

{

top++;

St[top]=b;

b=b->lchild;

}

p=NULL; /*p指向当前结点的前一个已访问的结点*/

flag=1; /*设置b的访问标记为已访问过*/

while (top!=-1 && flag)

{

b=St[top]; /*取出当前的栈顶元素*/

if (b->rchild==p) /*右子树不存在或已被访问,访问之*/

{

printf(\"%c \访问*b结点*/

top--;

p=b; }

else

{

b=b->rchild; flag=0; }

}

} while (top!=-1);

printf(\"\\n\");

/*p指向则被访问的结点*/

/*t指向右子树*/

/*设置未被访问的标记*/

}

}

void TravLevel(BTNode *b)

{

BTNode *Qu[MaxSize]; int front,rear; front=rear=0; if (b!=NULL)

printf(\"%c \

rear++; Qu[rear]=b;

while (rear!=front) {

front=(front+1)%MaxSize;

/*定义循环队列*/

/*定义队首和队尾指针*/

/*置队列为空队列*/

/*结点指针进入队列*/

/*队列不为空*/

b=Qu[front]; /*队头出队列*/

if (b->lchild!=NULL) /*输出左孩子,并入队列*/

{

printf(\"%c \

rear=(rear+1)%MaxSize;

Qu[rear]=b->lchild;

}

if (b->rchild!=NULL) /*输出右孩子,并入队列*/

{

printf(\"%c \

rear=(rear+1)%MaxSize;

Qu[rear]=b->rchild;

}

}

printf(\"\\n\");

}

void main()

{

BTNode *b;

CreateBTNode(b,\"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))\");

printf(\" 二叉树b:\");DispBTNode(b);printf(\"\\n\\n\");

printf(\" 层次遍历序列:\");

TravLevel(b);

printf(\"\\n\");

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

printf(\" 递归算法:\");PreOrder(b);printf(\"\\n\");

printf(\" 非递归算法1:\");PreOrder1(b);printf(\"\\n\");

printf(\" 非递归算法2:\");PreOrder2(b);printf(\"\\n\");

printf(\" 中序遍历序列:\\n\");

printf(\" 递归算法:\");InOrder(b);printf(\"\\n\");

printf(\" 非递归算法1:\");InOrder1(b);printf(\"\\n\");

printf(\" 非递归算法2:\");InOrder2(b);printf(\"\\n\");

printf(\" 后序遍历序列:\\n\");

printf(\" 递归算法:\");PostOrder(b);printf(\"\\n\");

printf(\" 非递归算法1:\");PostOrder1(b);printf(\"\\n\");

printf(\" 非递归算法2:\");PostOrder2(b);printf(\"\\n\");

}

三、 实验结果

实验7-1程序的运行结果如图所示:

实验7-2程序的运行结果如图所示:

四、 结论

(1).在实验7-1中,程序的运行结果分为6个部分,输出二叉树用的是括号表示法;求H节点的左孩子和右孩子分别是J和K;二叉树b的深度,即是二叉树的高度,总共有7层;节点个数,包括根节点、孩子节点和叶子节点,由二叉树的图形可以直接看出是14个;二叉树的叶子节点个数,即是最下一层的节点个数,共有6个。最后一个步骤是释放二叉树,即释放存储空间。

(2).在实验7-2中,程序的运行结果分为5大部分,首先是输入二叉树b,然后分别采用层次遍历、先序遍历、中序遍历和后序遍历二叉树,层次遍历算法是访问根节点(第1层),然后从左到右访问第2层的所有节点,最后从左到右访问第3层的所有节点、……、第h层的所有节点。先序遍历算法是先访问根节点,然后先序遍历左子树,最后先序遍历右子树。中序遍历算法是中序遍历左子树,然后访问根节点,最后中序遍历右子树。后序遍历算法则是后序遍历左子树,然后后序遍历右子树,最后访问根节点。

其中,先序、中序和后序遍历算法都运用了递归和非递归算法。

五、 问题与讨论

在完成本次实验7-1,7-2的过程中,大多数算法是课本上有源代码的,不过为了更好地锻炼和培养自己的动手能力和逻辑思维能力,我尝试着一边画图,在调试的时候不断修改程序,以便使运行结果更加可靠和准确。2个实验大量地运用到了循环体语句,如if……else循环,while循环等,这些都是基础知识,但在很多程序中不可避免地要用到,之前的C++课程知识的积累在学习数据结构这一门课程中大有帮助,由此也看出牢固地掌握基础知识并在其他地方中加以运用,不断修正和创新才会有更大的收获。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- yrrf.cn 版权所有 赣ICP备2024042794号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务