中根与后根构造二叉树与二叉树的匹配替换数据结构课程设计Word.docx

上传人:b****2 文档编号:25883646 上传时间:2023-06-16 格式:DOCX 页数:17 大小:19KB
下载 相关 举报
中根与后根构造二叉树与二叉树的匹配替换数据结构课程设计Word.docx_第1页
第1页 / 共17页
中根与后根构造二叉树与二叉树的匹配替换数据结构课程设计Word.docx_第2页
第2页 / 共17页
中根与后根构造二叉树与二叉树的匹配替换数据结构课程设计Word.docx_第3页
第3页 / 共17页
中根与后根构造二叉树与二叉树的匹配替换数据结构课程设计Word.docx_第4页
第4页 / 共17页
中根与后根构造二叉树与二叉树的匹配替换数据结构课程设计Word.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

中根与后根构造二叉树与二叉树的匹配替换数据结构课程设计Word.docx

《中根与后根构造二叉树与二叉树的匹配替换数据结构课程设计Word.docx》由会员分享,可在线阅读,更多相关《中根与后根构造二叉树与二叉树的匹配替换数据结构课程设计Word.docx(17页珍藏版)》请在冰豆网上搜索。

中根与后根构造二叉树与二叉树的匹配替换数据结构课程设计Word.docx

中根与后根构造二叉树与二叉树的匹配替换数据结构课程设计Word

成绩

 

南京工程学院

课程设计说明书(论文)

 

题目中根与后根构造二叉树与二叉树的匹配替换

课程名称数据结构

院(系、部、中心)计算机工程学院

专业计算机科学与技术

班级计算机卓越131

学生姓名羌秀君

学号202130404

设计地点信息楼

指导教师叶核亚

 

设计起止时间:

2016年5月10日至2016年5月20日

 

一、课程设计目的和要求

目的:

深入理解数据结构的基本理论,掌握数据存储结构的设计方法,掌握基于数据结构的各种操作的实现方法,训练对基础知识和基本方法的综合运用能力,增强对算法的理解能力,提高软件设计能力。

在实践中培养独立分析问题和解决问题的作风和能力。

要求:

熟练运用C++语言、基本数据结构和算法的基础知识,独立编制一个具有中等难度的、解决实际应用问题的应用程序。

通过题意分析、选择数据结构、算法设计、编制程序、调试程序、软件测试、结果分析、撰写课程设计报告等环节完成软件设计的全过程,不断地完善程序以提高程序的性能。

二、题意说明及分析

题目要求采用中根和后根序列构造一颗二叉树,并匹配替换二叉树的子树。

中根和后根构造:

由于后根可以确定一颗树的根,而中根在知道根的情况下可以确定左右子树的序列,因此这样递归,中根和后根可以确定一颗唯一的二叉树。

匹配替换二叉树:

1.通过遍历二叉树找到关键树根值在待匹配树中首次出现的位置,返回节点地址。

2.判断以找到的节点为根的子树和带匹配的树是否相同,采用递归算法。

3.确定以找到根节点的子树与带匹配的树相同,然后删除以此为根节点的子树,然后再将带替换的树复制到删除的节点。

三、算法设计与分析

算法设计思路、数据结构描述、流程图等

中根和后根构造算法:

设数组inlist[]和lalist[]分别表示一颗二叉树的中根和后根序列,两序列长度均为n。

1.由后根遍历的次序可知,该二叉树的根是lalist[n-1];改节点必定在中根次序中,设根节点在中根次序的第i个位置即inlist[i]=lalist[n-1]。

2.由中根遍历次序知,inlist[i]节点前的节点在根的左子树上,inlist[i]后的所有节点在根节点的右子树上。

因此,根的左子树由i个节点组成,子序列为:

左子树的后根次序lalist[0]....lalist[i-1]

左子树的中根次序inlist[0]...inlist[i-1]

根的右子树由n-j-1个节点,子序列为:

右子树的后根次序lalist[i]...lalist[n-2]

右子树的中根次序inlist[i+1]...inlist[n-1]

3.以此递归,可唯一确定一颗二叉树。

算法实现:

template

BinaryTree:

:

BinaryTree(Tlalist[],Tinlist[],intn){

this->root=create(lalist,inlist,n-1,n-1,n,root);

}

template

BinaryNode*BinaryTree:

:

create(Tlalist[],Tinlist[],intend,intinend,intn,BinaryNode*parent){

BinaryNode*p=NULL;

if(n>0)

{

p=newBinaryNode(lalist[end]);

inti=0;

while(i

=inlist[inend-i])

i++;

p->parent=parent;

p->right=create(lalist,inlist,end-1,inend,i,p);

p->left=create(lalist,inlist,end-i-1,inend-i-1,n-i-1,p);

}

returnp;

}

匹配替换二叉树算法:

通过遍历二叉树找到关键树根值在待匹配树中首次出现的位置,返回节点地址。

判断以找到的节点为根的子树和带匹配的树是否相同,采用递归算法。

确定以找到根节点的子树与带匹配的树相同,然后删除以此为根节点的子树,然后再将带替换的树复制到删除的节点。

算法实现:

//查找根节点

template

BinaryNode*BinaryTree:

:

searchhead(BinaryNode*q,BinaryNode*p){

BinaryNode*m=NULL;

if(q!

=NULL&&p!

=NULL){

if(q->data==p->data)

{

returnp;

}

if((m=searchhead(q->left,p))==NULL)

m=searchhead(q->right,p);

}

returnm;

}

//查找子树

template

BinaryNode*BinaryTree:

:

searchone(BinaryTree&bintree){

BinaryNode*p=searchhead(root,bintree.root);

if(p!

=NULL){

if(matchtree(p,bintree.root))

returnp;

else

returnNULL;

}

else

returnp;

}

//匹配子树

template

boolBinaryTree:

:

matchtree(BinaryNode*p,BinaryNode*q){

return(p==NULL&&q==NULL)||((q!

=NULL&&p!

=NULL)&&(p->data==q->data))&&(matchtree(p->left,q->left)&&matchtree(p->right,q->right));

}

 

四、源程序

1.二叉树节点类

template

classBinaryNode{

public:

Tdata;//数据域

BinaryNode*left,*right,*parent;//指针域,分别指向左右孩子节点

//构造函数

BinaryNode(Tdata,BinaryNode*left=NULL,BinaryNode*right=NULL,BinaryNode*parent=NULL){

this->data=data;

this->left=left;

this->right=right;

this->parent=parent;

}

};

二叉树类

#include

usingnamespacestd;

#include"BinaryTreeNode.h"

template

classBinaryTree{

public:

BinaryNode*root;

BinaryTree();//构造空二叉树

BinaryTree(Tlalist[],Tinlist[],intn);//以中根和后根序列构造二叉树

~BinaryTree();//析构

boolempty();//判断是否为空二叉树

friendostream&operator<<<>(ostream&out,BinaryTree&);//输出

voidpreOrder();//输出先根次序遍历序列

stringgetinOrder(BinaryNode*);//获得中根次序遍历的字符串

stringgetpostOrder(BinaryNode*);//获得后根次序遍历的字符串

voidremove(BinaryNode*parent,boolleftchild);//删除parent节点的左或右子树

BinaryNode*searchone(BinaryTree&);//查找子树

BinaryNode*searchhead(BinaryNode*q,Tkey);//查找头结点

boolmatchtree(BinaryNode*p,BinaryNode*q);

voiddestroy(BinaryNode*p);

boolreplace(BinaryTree&key,BinaryTree&re);

private:

voidpreOrder(BinaryNode*p);//先根次序遍历以p节点为根的子树

voidpostOrder(BinaryNode*p,string&str);//后根

voidinOrder(BinaryNode*p,string&str);//中根次序遍历以p节点为根的子树

BinaryNode*create(Tlalist[],Tinlist[],intend,intinend,intn,BinaryNode*);

BinaryNode*copy(BinaryNode*);

 

};

//析构

template

BinaryTree:

:

~BinaryTree()

{

destroy(root);

}

//判断树是否为空

template

boolBinaryTree:

:

empty()

{

returnthis->root==NULL;

}

//构造空二叉树

template

BinaryTree:

:

BinaryTree()

{

this->root=NULL;

}

//输出先根次序遍历的序列

template

ostream&operator<<<>(ostream&out,BinaryTree&btree)

{

out<<"先根次序遍历二叉树";

btree.preOrder(btree.root);

out<

returnout;

}

template

voidBinaryTree:

:

preOrder(BinaryNode*p)

{

if(p==NULL)

{

cout<<"^";

}

else

{

cout<data<<"";

preOrder(p->left);

preOrder(p->right);

}

}

//中根和后根构造二叉树

template

BinaryTree:

:

BinaryTree(Tlalist[],Tinlist[],intn)

{

this->root=create(lalist,inlist,n-1,n-1,n,root);

}

template

BinaryNode*BinaryTree:

:

create(Tlalist[],Tinlist[],intend,intinend,intn,BinaryNode*parent)

{

BinaryNode*p=NULL;

if(n>0)

{

p=newBinaryNode(lalist[end]);

inti=0;

while(i

=inlist[inend-i])

i++;

p->parent=parent;

p->right=create(lalist,inlist,end-1,inend,i,p);

p->left=create(lalist,inlist,end-i-1,inend-i-1,n-i-1,p);

}

returnp;

}

//删除子树

template

voidBinaryTree:

:

destroy(BinaryNode*p)

{

if(p!

=NULL)

{

destroy(p->left);

destroy(p->right);

deletep;

}

}

//查找根节点

template

BinaryNode*BinaryTree:

:

searchhead(BinaryNode*q,Tkey)

{

BinaryNode*m=NULL;

if(q!

=NULL)

{

if(q->data==key)

{

returnq;

}

if((m=searchhead(q->left,key))==NULL)

m=searchhead(q->right,key);

}

returnm;

}

//查找子树

template

BinaryNode*BinaryTree:

:

searchone(BinaryTree&bintree)

{

BinaryNode*p=searchhead(root,bintree.root->data);

if(p!

=NULL)

{

if(matchtree(p,bintree.root))

returnp;

else

returnNULL;

}

else

returnp;

}

//匹配子树

template

boolBinaryTree:

:

matchtree(BinaryNode*p,BinaryNode*q)

{

if(q==NULL&&p==NULL)

returntrue;

if(p==NULL||q==NULL)

returnfalse;

if(p->data!

=q->data)

returnfalse;

return(matchtree(p->left,q->left)&&matchtree(p->right,q->right));

}

//替换

template

boolBinaryTree:

:

replace(BinaryTree&key,BinaryTree&re)

{

BinaryNode*p=searchone(key);

if(p!

=NULL)

{

//替换(搜到的头不销毁)

destroy(p->left);

destroy(p->right);

p->data=re.root->data;

p->left=copy(re.root->left);

p->right=copy(re.root->right);

returntrue;

}

else

returnNULL;

}

//二叉树复制

template

BinaryNode*BinaryTree:

:

copy(BinaryNode*p)

{

BinaryNode*q=NULL;

if(p!

=NULL)

{

q=newBinaryNode(p->data);

q->parent=p->parent;

q->left=copy(p->left);

q->right=copy(p->right);

}

returnq;

}

//获得中根遍历下的字符串

template

stringBinaryTree:

:

getinOrder(BinaryNode*p)

{

stringstr;

inOrder(p,str);

returnstr;

}

template

voidBinaryTree:

:

inOrder(BinaryNode*p,string&str)

{

if(p!

=NULL)

{

inOrder(p->left,str);

str+=p->data;

inOrder(p->right,str);

}

}

//获得后根遍历下的字符串

template

stringBinaryTree:

:

getpostOrder(BinaryNode*p)

{

stringstr;

postOrder(p,str);

returnstr;

}

template

voidBinaryTree:

:

postOrder(BinaryNode*p,string&str)

{

if(p!

=NULL)

{

postOrder(p->left,str);

postOrder(p->right,str);

str+=p->data;

}

}

主cpp文件

#include"BinaryTree.h"

#include

#include

#include

usingnamespacestd;

intmain(){

charlalist[]="GDBEHFCA";

charinlist[]="DGBAECHF";

charinkey[]="ECHF";

charlakey[]="EHFC";

charinrep[]="LJMIK";

charlarep[]="LMJKI";

BinaryTreetree(lalist,inlist,8);

BinaryTreekeytree(lakey,inkey,4);

BinaryTreereptree(larep,inrep,5);

cout<

cout<<"二叉关键子树"<

cout<<"待替换的子树"<

cout<<"替换后"<

tree.replace(keytree,reptree);

cout<

return0;

}

 

 

五、结果及分析

结果:

 

分析:

1.通过中根charlalist[]="GDBEHFCA";后根charinlist[]="DGBAECHF";构造一颗二叉树TREE。

2.通过中根charinkey[]="ECHF";后根charlakey[]="EHFC";构造一颗关键二叉树KEYTREE。

3.通过中根charinrep[]="LJMIK";后根charlarep[]="LMJKI";构造一颗待替换的树REPTREE;

4.通过KEYTREE的根在TREE中找到对应的地址,然后判断通过找到以此地址为根的子树是否与KEYTREE相同。

5.相同将删除以找到的地址为根的子树。

6.复制REPTREE到TREE删除的子树上。

六、总结与思考

1,首先一开始对这个题目没有思路,可能是书上代码不熟悉的原因,所以我在做实验之前,把书上老师上课讲的二叉树这边的功能都实现了一遍,对二叉树的操作有了最基本的操作了解之后,慢慢入门。

2,然后我仔细分析了这条题目,要用到的函数都写了下来,把要实现的操作都用草图的形式画了出来,这样我就对我该先做什么,后做什么,这种目的实现的方法有了自己的思路。

3,我在着手写程序的时候,出现了很多问题,在中后根构造上花了不少时间,总之还是自己不够细心。

4,经过自己的努力,我把那些应该用到的功能函数都实现好了。

还有其他地方也进行了改进,实验终于成功了。

5,总的来说,做实验还是要边写代码边画图,这样思路清晰,还要细心一点,不能忘记任何一个步奏,仔细思考了一下,觉得一方面要多写多实践增加自己的经验,另一方面要多思考,多调试,要能看懂错误,并迅速想到解决方案,这需要长时间的积累。

还有就是实在想不出来的问题,可以和同学进行交流探讨,说不定问题就解决了。

毕竟一个人的能力是有限的,通过交流可以共同学习,互相进步。

 

教师评语:

(本资料素材和资料部分来自网络,仅供参考。

请预览后才下载,期待您的好评与关注!

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 自然景观

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1