数据结构 二叉树 实验报告.docx
- 文档编号:8944530
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:22
- 大小:57.20KB
数据结构 二叉树 实验报告.docx
《数据结构 二叉树 实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构 二叉树 实验报告.docx(22页珍藏版)》请在冰豆网上搜索。
数据结构二叉树实验报告
中南大学
《数据结构》课程实验
实验报告
题目线性表的操作
学生姓名柯鑫鑫
学生学号3901130604
专业班级1306
1.
需求分析
2.1、掌握用指针类型描述、访问和处理二叉树的运算;
3.2、掌握二叉树的结构特征,以及各种存储结构的特点及适用范围;
4.3、熟练掌握递归程序设计方法、以及栈的应用
5.概要设计
创建数
创建栈结构
创建队列结构
递归遍历二叉树
非递归栈的方式遍历二叉树
非递归队列的方式遍历二叉树
创建统计二叉树的节点个数、度为1、度为2和叶子节点的个数,以及数据值的最大值和最小值的方法
6.详细设计
二叉树的创建
递归法构造二叉树
#include
usingnamespacestd;
structTree //用结构体创建节点
{
charelement;
Tree*lchilden;
Tree *rchilden;
};
Tree *Create() //创建树
{
charch;
cin>>ch;
if(ch=='#' )
{
returnNULL;
}
else
{
Tree*root=(Tree*)malloc(sizeof(Tree));
root->element=ch;
root->lchilden=Create(); //左孩子递归
root->rchilden=Create(); //右孩子递归
returnroot;
}
}
voidvisit(Tree*t) //访问方法
{
cout<
}
voidpreOrder(Tree*t) //遍历二叉树
{
if (t!
=NULL) {
visit(t);
preOrder(t->lchilden);
preOrder(t->rchilden);
}
}
intmain() //测试
{
Tree*p;
p =Create();
preOrder(p);
system("pause");
return0;
}
如何正确的理解递归法?
递归一定要有返回,此例中有两个返回的条件returnNULL;returnroot; 递归是一个不断进栈和出栈的过程。
出栈时理论上数据是没了,但是因为是在堆里创建结构体所以结构体还在,通过一个头指针把整个链表串起来。
这个程序是以先序的方式输入数据的;以一个节点为例
应输入A##;
应为A不为#,进入else语句。
先执行左孩子递归,此时输入为#,returnNULL;左孩子的递归执行完了,
语句往下走,执行右孩子递归。
此时输入为#,returnNULL;右孩子的递归执行完了。
程序再往下走,returnroot;返回指针root;
此时root就为头指针;
现在已两个结点为例
应输入AB###;
应为A不为#,进入else语句。
先执行左孩子递归,此时输入为B,root指向B;B进入递归(A->lchilden->B)
先执行左孩子递归,此时输入为#,returnNULL;(B的左孩子的全部递归执行完了)
语句往下走,执行右孩子递归。
此时输入为#,returnNULL;(B的右孩子右孩子的递归执行完了。
)
程序再往下走,returnroot;返回指针root;
此时root指向A;
(A的左孩子全部执行完了)
程序进入了下一条语句执行A的右孩子
此时输入为#,returnNULL;(此时A的右孩子的递归执行完了,)
程序再往下走,returnroot;返回root;
此时root为头指针。
此时应输入
ABC##DE#G##F###
模拟程序执行如下
应为A不为#,进入else语句。
先执行左孩子递归,此时输入为B,root指向B;B进入递归(A->lchilden->B)
应为B不为#,进入else语句。
先执行左孩子递归,此时输入为C,root指向C;C进入递归(A->lchilden->B->lchilden->C)
先执行左孩子递归,此时输入为#,returnNULL;(C的左孩子的全部递归执行完了)
语句往下走,执行右孩子递归。
此时输入为#,returnNULL;(C的右孩子右孩子的递归执行完了)
程序再往下走,returnroot;返回指针root;
此时root指向B;
(B的左孩子全部执行完了)
程序进入了下一条语句执行B的右孩子
语句往下走,执行右孩子递归。
应为E不为#,进入else语句。
先执行左孩子递归,此时输入为#,returnNULL;(E的左孩子的全部递归执行完了)
语句往下走,执行右孩子递归。
.................................................
遍历二叉树递归
voidpreOrder(Tree*t)//遍历二叉树
{
if(t!
=NULL){
visit(t);
preOrder(t->lchilden);
preOrder(t->rchilden);
}
}
voidinOrder(Tree*t)//遍历二叉树
{
if(t!
=NULL){
preOrder(t->lchilden);
visit(t);
preOrder(t->rchilden);
}
}
voidpostOrder(Tree*t)//遍历二叉树
{
if(t!
=NULL){
preOrder(t->lchilden);
preOrder(t->rchilden);
visit(t);
}
}
队列遍历的设计方法
structQnode{//创建链表队列的节点
chardata;
Qnode*next;
Tree*tree;//用来标志在树中的位置(沟通的树和下面创建的链表队列)
};
structLinkQueue{//创建队列
Qnode*front;
Qnode*rear;
};
LinkQueue*InitQueue(LinkQueue*q){//构造一个空队列
//q=(LinkQueue*)malloc(sizeof(LinkQueue));
q->front=q->rear=(Qnode*)malloc(sizeof(Qnode));
if(!
q->front)exit(OVERFLOW);
q->front->next=NULL;
returnq;
}
LinkQueue*DestroyQueue(LinkQueue*q){//销毁队列
while(q->front){
q->rear=q->front->next;
free(q->front);
q->front=q->rear;
}
returnq;
}
LinkQueue*EnQueue(LinkQueue*q,Tree*m){
Qnode*p=(Qnode*)malloc(sizeof(Qnode));//插入元素e为Q的新的队尾元素
p->data=m->element;
p->next=NULL;
q->rear->next=p;
q->rear=p;
q->rear->tree=m;//保存下现在节点在树中的位置;
returnq;
}
charDeQueue(LinkQueue*q,Tree*m){//若队列不为空,则删除Q的对头元素,用e返回其值
Qnode*p=q->front->next;
chare=p->data;
m=p->tree;//把要销毁的队列的节点在树中的位置用m指针引用
q->front->next=p->next;
if(q->rear==p)q->rear=q->front;
free(p);
if(m->lchilden!
=NULL){//判断销毁后的节点的左孩子还有吗;
EnQueue(q,m->lchilden);
}
if(m->rchilden!
=NULL){//判断销毁后的节点的右孩子还在吗;
EnQueue(q,m->rchilden);
}
returne;
}
intqueueempty(LinkQueue*q)//判断队列是否为空
{
if(q->front->next==NULL)
return1;
return0;
}
intmain()
{
Tree*q;
q=Create();
LinkQueue*p=newLinkQueue;
InitQueue(p);
EnQueue(p,q);
Tree*t=q;
Tree*k=q;
boolstep=0;
while(queueempty(p)!
=1){
cout< } system("pause"); return0; } 运行结果如下 说明: 在创建链表节点时一定要多一个树的指针;用来标志位置如下图 非递归栈的创建方法 创建一个栈类 classstack//创建一个栈类 { public: doublearray[MAX]; inttop; Tree*tree[MAX]; public: stack() { top=0; } voidSqstacktp(){//将顺序栈s置为空 top=0; } boolisEmpty(){ if(top>0) returnfalse; else returntrue; } doublesize(){ returntop; } doubleistop(){//取栈顶元素 if(top==0) return0; else returnarray[top-1]; } voidpush(doublex,Tree*p){//若栈s未满,将元素x压入栈中;否则,栈的状态不变并给出出错信息 if(top==MAX) cout<<"overflow"< else tree[top]=p; array[top]=x; top++;//x进栈 } Tree*pop(Tree*p){//若栈不空,则删去栈顶元素并返回元素值,否则返回空元素NULL if(top==0) return0; else{ top--; //栈顶指针减1 returntree[top]; } } voidprint(){//输出栈里的元素 inttemp=top; while(temp! =0) cout< } }; 栈的非递归访问 voiditerative_preorder(Tree*p){//非递归算法的先序遍历 stacktree; if(p! =NULL){ tree.push(p->element,p); while(! tree.isEmpty()){ p=tree.pop(p); visit(p); totalNumber(p); numberOfTree(p); get_the_max(p); get_the_min(p); if(p->rchilden! =NULL) tree.push(p->rchilden->element,p->rchilden);/*leftchildpushed*/ if(p->lchilden! =NULL) tree.push(p->lchilden->element,p->lchilden);/*afterrighttobe*/ }/*atthetopofthestack*/ } } 采用非递归的编程方法,分别统计二叉树的节点个数、度为1、度为2和叶子节点的个数,以及数据值的最大值和最小值。 voidvisit(Tree*t)//访问方法 { if(t! =NULL) cout< } voidtotalNumber(Tree*t){ x++; } voidnumberOfTree(Tree*t){ if(t->lchilden! =NULL&&t->rchilden! =NULL)number2++; if((t->lchilden! =NULL&&t->rchilden==NULL)||(t->lchilden==NULL&&t->rchilden! =NULL))number1++; if(t->lchilden==NULL&&t->rchilden==NULL)number0++; } intget_the_max(Tree*t){ if(t->element-'0'>max)max=t->element-'0'; returnmax; } intget_the_min(Tree*t){ if(t->element-'0' returnmin; } 测试程序 intmain() { Tree*p; cout<<"creatatreewiththepreOder: "; p=Create(); cout<<"thepreOderofthetreeis"< preOrder(p); cout< cout<<"theinOderofthetreeis"< inOrder(p); cout< cout<<"thepostOrderofthetreeis"< postOrder(p); cout< cout<<"thequeOderofthetreeis"< queOder(p); cout< cout<<"tjeiterative_preorderofthetreeis"< iterative_preorder(p); cout< cout<<"thetotalnumberofthetreeis"< cout< cout<<"thenumberof0is"< cout< cout<<"thenumberof1is"< cout< cout<<"thenumberof2is"< cout< cout<<"themaxis"< cout< cout<<"theminis"< cout< system("pause"); return0; } 7.调试分析 5用户使用说明 要用先序的方式输入二叉树 6测试结果 7附录 #include usingnamespacestd; constintMAX=1000; staticintx=0; staticintnumber0=0; staticintnumber1=0; staticintnumber2=0; staticintmax=0; staticintmin=10; structTree//用结构体创建节点 { charelement; Tree*lchilden; Tree*rchilden; }; classstack//创建一个栈类 { public: doublearray[MAX]; inttop; Tree*tree[MAX]; public: stack() { top=0; } voidSqstacktp(){//将顺序栈s置为空 top=0; } boolisEmpty(){ if(top>0) returnfalse; else returntrue; } doublesize(){ returntop; } doubleistop(){//取栈顶元素 if(top==0) return0; else returnarray[top-1]; } voidpush(doublex,Tree*p){//若栈s未满,将元素x压入栈中;否则,栈的状态不变并给出出错信息 if(top==MAX) cout<<"overflow"< else tree[top]=p; array[top]=x; top++;//x进栈 } Tree*pop(Tree*p){//若栈不空,则删去栈顶元素并返回元素值,否则返回空元素NULL if(top==0) return0; else{ top--; //栈顶指针减1 returntree[top]; } } voidprint(){//输出栈里的元素 inttemp=top; while(temp! =0) cout< } }; Tree*Create()//创建树 { charch; cin>>ch; if(ch=='#') { returnNULL; } else { Tree*root=(Tree*)malloc(sizeof(Tree)); root->element=ch; root->lchilden=Create();//左孩子递归 root->rchilden=Create();//右孩子递归 returnroot; } } voidvisit(Tree*t)//访问方法 { if(t! =NULL) cout< } voidtotalNumber(Tree*t){ x++; } voidnumberOfTree(Tree*t){ if(t->lchilden! =NULL&&t->rchilden! =NULL)number2++; if((t->lchilden! =NULL&&t->rchilden==NULL)||(t->lchilden==NULL&&t->rchilden! =NULL))number1++; if(t->lchilden==NULL&&t->rchilden==NULL)number0++; } intget_the_max(Tree*t){ if(t->element-'0'>max)max=t->element-'0'; returnmax; } intget_the_min(Tree*t){ if(t->element-'0' returnmin; } voidpreOrder(Tree*t)//遍历二叉树 { if(t! =NULL){ visit(t); preOrder(t->lchilden); preOrder(t->rchilden); } } voidinOrder(Tree*t)//遍历二叉树 { if(t! =NULL){ preOrder(t->lchilden); visit(t); preOrder(t->rchilden); } } voidpostOrder(Tree*t)//遍历二叉树 { if(t! =NULL){ preOrder(t->lchilden); preOrder(t->rchilden); visit(t); } } voiditerative_preorder(Tree*p){//非递归算法的先序遍历 stacktree; if(p! =NULL){ tree.push(p->element,p); while(! tree.isEmpty()){ p=tree.pop(p); visit(p);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 二叉树 实验报告 二叉 实验 报告