数据结构课程设计二叉树遍历C++语言.docx

上传人:b****4 文档编号:12101550 上传时间:2023-04-17 格式:DOCX 页数:38 大小:118.90KB
下载 相关 举报
数据结构课程设计二叉树遍历C++语言.docx_第1页
第1页 / 共38页
数据结构课程设计二叉树遍历C++语言.docx_第2页
第2页 / 共38页
数据结构课程设计二叉树遍历C++语言.docx_第3页
第3页 / 共38页
数据结构课程设计二叉树遍历C++语言.docx_第4页
第4页 / 共38页
数据结构课程设计二叉树遍历C++语言.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

数据结构课程设计二叉树遍历C++语言.docx

《数据结构课程设计二叉树遍历C++语言.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计二叉树遍历C++语言.docx(38页珍藏版)》请在冰豆网上搜索。

数据结构课程设计二叉树遍历C++语言.docx

数据结构课程设计二叉树遍历C++语言

 

淮阴工学院实践报告

数据结构课程设计

 

设计题目:

二叉树遍历

系别:

计算机工程学院

专业:

软件工程

班级:

软件1111

学生姓名:

周淼学号:

1111315217

起止日期:

2012年12月24日~2012年12月30日

指导教师:

寇海洲

 

摘要:

现代社会生活中,计算机扮演着重要角色,而随着计算机运行速度的不断加快,对数据的处理能力也日益增强,因此,程序所涉及的数据成爆发式增长。

随之而来的问题就是如何科学有效的对数据进行操作,使得计算机的时间和空间利用率最高。

针对这样的问题,我选择了二叉树对数据的各种操作作为我的课程设计主题,希望通过课程设计来提高对数据的处理能力,促进对数据结构课程的理解,在日后面向对象的程序设计中科学的规划数据结构。

在本次课程设计中,二叉树的建立使用了递归算法,遍历则同时使用了递归与非递归的算法,同时,在遍历算法的实现中使用了栈结构与队列结构,这大大方便了二叉树的遍历。

在前序、中序、后续遍历算法中,分别实现了递归与非递归算法,从实际应用中体验了递归这一算法的优越性。

关键词:

二叉树建立,递归与非递归,遍历,栈,队列

编号:

47

淮阴工学院软件工程专业

数据结构课程设计答辩记录

课题名称:

二叉树的算法

班级软件1111学号1111315217姓名周淼

答辩记录

问题1:

课题中涉及到哪些数据结构和算法?

答:

1)数组,二叉树,栈,队列,线性表

2)二叉树的中序、前序、后序的递归、非递归遍历算法,层次序遍历非递归算法,栈、队列的实现算法

 

问题2:

课题研究和设计中的关键技术是什么?

答:

关键技术是二叉树的建立,以及栈结构、队列的算法实现

 

问题3:

课题的主要功能和模块有哪些?

答:

1)主要功能:

根据数据建立二叉树,实现二叉树的中序、前序、后序遍历

2)模块:

栈的应用,队列结构的应用,二叉树的操作

 

问题4:

课题在实现过程中遇到的主要难点有哪些?

答:

遍历二叉树过程中栈结构以及队列的使用

 

问题5:

课题中未能实现的功能有哪些?

答:

以树形结构输出完全二叉树

记录人:

寇海洲2012年12月28日

1需求分析

1.1二叉树与树结构

树结构的是建立在数据逻辑结构基础上的数据结构类型,二叉树则是树结构中最常见和使用最多的类型。

通过对二叉树的操作,可以实现多种数据操作,如排序、查找等。

一个好的二叉树遍历算法应包含以下功能:

1)以递归和非递归方法建立二叉树或完全二叉树;

2)实现二叉树的前序遍历、中序遍历、后序遍历;

3)每种遍历算法皆以递归和非递归方法实现;

4)在具体实现时应用其他数据结构类型对数据进行操作,如:

栈,队列,数组。

1.2面向对象的程序设计

在面向对象的程序设计中,模板的使用很普遍,因此,如何在程序设计中使用模板使得方法的实现与定义分开,程序模块化,既方便了程序设计者,又为程序的后期维护带来便利。

1.3二叉树遍历的应用

当数据以数组或文档形式存储在内存时,其数据之间虽有逻辑联系,却过于分散,因此,建立二叉树以存储数据并且遍历该二叉树,可以从逻辑上理顺数据之间的关系,使得原本分数的数据排列的有序且可靠。

一个好的二叉树应用算法其空间复杂度与时间复杂度必然最低,这样给程序带来时间和空间上的极大优化。

1.4软件运行环境:

VisualC++6.0版本

2概要设计

2.1总体功能结构

二叉树的遍历,主要包含以下功能:

1)建立二叉树:

递归方法、非递归方法

2)中序遍历:

递归方法、非递归方法

3)前序遍历:

递归方法、非递归方法

4)后序遍历:

递归方法、非递归方法

5)栈结构使用:

遍历时输入临时变量以保存

6)队列结构使用:

完全二叉树遍历时用以存储数据

2.2数据结构部分设计

2.2.1结点结构

二叉树结点结构中包数据域(data),指针域(*leftChild,*rightChild)。

结点结构的代码如下:

structBinTreeNode{//树结点

Tdata;

BinTreeNode*leftChild;

BinTreeNode*rightChild;

BinTreeNode():

leftChild(NULL),rightChild(NULL){}

BinTreeNode(Tx,BinTreeNode*l=NULL,BinTreeNode*r=NULL)

:

leftChild(l),rightChild(r){

data=x;

}

栈结构结点包含数据域(data),指针域(*link),实现代码如下:

structStackNode{//栈结点

Tdata;

StackNode*link;

StackNode(Td=0,StackNode*next=NULL):

link(next),data(d){}

};

队列结构结点包含数据域(data),指针域(*link),实现代码如下:

structLinkNode{

Tdata;

LinkNode*link;

LinkNode(LinkNode*ptr=NULL){

link=ptr;

}

LinkNode(constT&item,LinkNode*ptr=NULL){

data=item;link=ptr;

}

};

};

2.2.2二叉树结构

二叉树包含了递归、非递归建树过程,递归、非递归的前序遍历、中序遍历、后续遍历过程。

二叉树的类定义包含各种操作,实现代码如下:

templateclassBinaryTree{//二叉树类定义

public:

BinaryTree():

root(NULL){}

BinaryTree(Tvalue):

root(NULL){

RefValue=value;

}

BinaryTree(BinaryTree&s){

if(this!

=&s){

root=Copy(s.root);

}

}

~BinaryTree(){

destroy(root);

}

BinTreeNode*Parent(BinTreeNode*t){

return(root==NULL||root==t)?

NULL:

Parent(root,t);

}

BinTreeNode*LeftChild(BinTreeNode*t){

return(t!

=NULL)?

t->leftChild:

NULL;

}

BinTreeNode*RightChild(BinTreeNode*t){

return(t!

=NULL)?

t->rightChild:

NULL;

}

voidPreOrder(void(*visit)(BinTreeNode*t)){

PreOrder(root,visit);

}

voidInOrder(void(*visit)(BinTreeNode*t)){

InOrder(root,visit);

}

voidPostOrder(void(*visit)(BinTreeNode*t)){

PostOrder(root,visit);

}

voidCreateCompBinTree(T*CBT,intnum){//建立完全二叉树

CreateCompBinTree(CBT,num,0,root);

}

voidlevelOrder(void(*visit)(BinTreeNode*t));//层次序遍历

voidPreOrder1(void(*visit)(BinTreeNode*t));//非递归前序遍历

voidInOrder1(void(*visit)(BinTreeNode*t));//非递归中序遍历

voidPostOrder1(void(*visit)(BinTreeNode*t));//非递归后序遍历

friendistream&operator>>(istream&in,BinaryTree&Tree){//输入二叉树

Tree.CreateBinTree(in,Tree.root);

returnin;

}

栈结构的定义中,包含了对数据的入栈、出栈、清空等基本操作,实现代码如下

template

classLinkedStack{

private:

StackNode*top;

public:

LinkedStack():

top(NULL){}//无头结点

~LinkedStack(){

makeEmpty();

}

voidPush(constT&x);

boolPop(T&x);

boolIsEmpty()const{

returntop==NULL;

}

boolIsFull()const{

returnfalse;

}

voidmakeEmpty();

friendostream&operator<<(ostream&os,LinkedStack&s){

os<<"StackSize:

"<

StackNode*p=s.top;

inti=0;

while(p){

os<<++i<<":

"<data<

p=p->link;

}

returnos;

}

};

template

voidLinkedStack:

:

makeEmpty(){

StackNode*p;

while(top){

p=top;

top=top->link;

deletep;

}

}

队列的类定义,实现了对数据的入队、出队操作,实现代码如下:

templateclassLinkedQueue{//无头结点

public:

LinkedQueue(){

rear=NULL;

front=NULL;

}

~LinkedQueue(){

makeEmpty();

}

boolEnQueue(constT&x);

boolDeQueue(T&x);

voidmakeEmpty();

boolIsEmpty()const{

returnfront==NULL;

}

friendostream&operator<<(ostream&os,LinkedQueue&Q){

LinkNode*p=Q.front;

inti=0;

while(p){

os<<"#"<<++i<<":

"<data<

p=p->link;

}

os<<"QueueSize:

"<

returnos;

}

voidoutput();

protected:

LinkNode*front,*rear;

};

3详细设计

3.1建立二叉树

3.1.1功能描述

二叉树是程序的核心,如何合理的建立至关重要。

本实例中使用递归和非递归方法分别建立二叉树,二叉树的数据来源于程序开始时建立的数组。

建立后的二叉树保存,并且留作之后的遍历使用。

3.1.2算法原理

本实例使用的是完全二叉树,首先建立头结点,并且保存数据,然后根据递归方法,分别建立其左右孩子结点,且左右孩子结点的指针域指向空。

3.1.3具体程序

以递归方式建立二叉树,每次建立一个结点后,将其左右孩子指针域置空,成为叶子结点。

具体实现代码如下:

templatevoidBinaryTree:

:

CreateBinTree(istream&in,BinTreeNode*&subTree){

Titem;

if(in>>item){

if(item!

=RefValue){

subTree=newBinTreeNode(item);//CreateRoot

assert(subTree);

CreateBinTree(in,subTree->leftChild);//Createleftchildtree

CreateBinTree(in,subTree->rightChild);//Createreghtchildtree

}

else

{

subTree=NULL;

}

}

}

//建立完全二叉树

templatevoidBinaryTree:

:

CreateCompBinTree(T*CBT,intnum,intrt,BinTreeNode*&subTree){

if(rt>=num){

subTree=NULL;

}

else{

subTree=newBinTreeNode(CBT[rt]);

}

CreateCompBinTree(CBT,num,2*rt+1,subTree->leftChild);

CreateCompBinTree(CBT,num,2*rt+2,subTree->rightChild);

}

}

3.2前序遍历

3.2.1功能原理

通过前序遍历,将二叉树中的数据按照前序遍历的结果输出,达到前序便利的目的,方便数据的使用。

3.2.2算法原理

前序遍历使用了递归与非递归两种方法,在程序头文件中定义了两个函数分别实现其功能。

递归时,输出第一个结点数据时,找到数据,然后找到其后面的数据,然后依次递归输出。

非递归时,使用栈和队列结构,将部分数据保存在栈或队列中,等待将数据放到合适位置。

3.2.3具体程序

1)递归算法实现:

templatevoidBinaryTree:

:

PreOrder(BinTreeNode*subTree,void(*visit)(BinTreeNode*t)){

if(subTree!

=NULL){

visit(subTree);

PreOrder(subTree->leftChild,visit);

PreOrder(subTree->rightChild,visit);

}

}

2)非递归算法实现:

templatevoidBinaryTree:

:

PreOrder1(void(*visit)(BinTreeNode*t)){

LinkedStack*>S;

BinTreeNode*p=root;

S.Push(NULL);

while(p!

=NULL){

visit(p);//访问结点

if(p->rightChild!

=NULL)

S.Push(p->rightChild);//预留右指针在栈中

if(p->leftChild!

=NULL)

p=p->leftChild;//进左子树

elseS.Pop(p);//左子树为空,由堆栈弹出

}

}

3.3中序遍历

3.3.1功能原理

通过中序遍历,将二叉树中的数据按照中序序遍历的结果输出,达到中序遍历的目的,实现数据的最优,方便数据的使用。

3.3.2算法原理

中序遍历使用了递归与非递归两种方法,在程序头文件中定义了两个函数分别实现其功能。

递归时,输出第一个结点数据时,找到数据,然后依次找到其后面的数据,然后依次递归输出。

非递归时,使用栈和队列结构,将部分数据保存在栈与队列中,等待将数据放到合适位置。

3.3.3具体程序

1)递归算法实现:

templatevoidBinaryTree:

:

InOrder(BinTreeNode*subTree,void(*visit)(BinTreeNode*t)){

if(subTree!

=NULL){

InOrder(subTree->leftChild,visit);

visit(subTree);

InOrder(subTree->rightChild,visit);

}

}

2)非递归算法实现:

templatevoidBinaryTree:

:

InOrder1(void(*visit)(BinTreeNode*t)){//非递归中序遍历

LinkedStack*>S;

BinTreeNode*p=root;

while(p!

=NULL||!

S.IsEmpty()){

while(p!

=NULL){//遍历指针向左下移动

S.Push(p);//该子树沿途结点进栈

p=p->leftChild;

}

if(!

S.IsEmpty()){//栈不空时退栈

S.Pop(p);visit(p);//退栈,访问

p=p->rightChild;//遍历指针进到右子女

}

}

}

3.4后序遍历

3.4.1功能原理

通过后序遍历,将二叉树中的数据按照后序遍历的结果输出,达到后序遍历的目的,实现数据的最优,方便数据的使用。

3.4.2算法原理

后序遍历使用了递归与非递归两种方法,在程序头文件中定义了两个函数分别实现其功能。

递归时,输出第一个结点数据时,找到数据,然后依次找到其后面的数据,然后依次递归输出。

非递归时,使用栈和队列结构,将部分数据保存在栈与队列中,等待将数据放到合适位置。

3.4.3具体程序

1)递归算法实现:

templatevoidBinaryTree:

:

PostOrder(BinTreeNode*subTree,void(*visit)(BinTreeNode*t)){

if(subTree!

=NULL){

PostOrder(subTree->leftChild,visit);

PostOrder(subTree->rightChild,visit);

visit(subTree);

}

}2)非递归算法实现:

templatevoidBinaryTree:

:

PostOrder1(void(*visit)(BinTreeNode*t)){

//非递归后序遍历

LinkedStack>S;

stkNodew;

BinTreeNode*p=root;//p是遍历指针

do{

while(p!

=NULL){

w.ptr=p;

w.tag=stkNode:

:

L;

//枚举类型定义在structstkNode中,如定义为全局性就简单了

S.Push(w);

p=p->leftChild;

}

intcontinue1=1;

while(continue1&&!

S.IsEmpty()){

S.Pop(w);p=w.ptr;

switch(w.tag){//判断栈顶的tag标记

casestkNode:

:

L:

w.tag=stkNode:

:

R;

S.Push(w);

continue1=0;

p=p->rightChild;break;

casestkNode:

:

R:

visit(p);break;

}

}

}while(!

S.IsEmpty());//继续遍历其他结点

cout<

}

3.5层次序非递归遍历

3.5.1功能原理

层次序非递归遍历,依据的是递归原理,每次遍历一个结点后,同时让其左右孩子入队,以便达到层次序的目的。

3.5.2算法原理

每次遍历完一个结点后,检查该结点是否为叶子结点,如果是叶子结点则继续下一结点的遍历,否则其左右孩子入队,继续遍历。

3.5.3具体程序

templatevoidBinaryTree:

:

levelOrder(void(*visit)(BinTreeNode*t)){//层次序遍历

if(root==NULL)return;

LinkedQueue*>Q;

BinTreeNode*p=root;

visit(p);Q.EnQueue(p);

while(!

Q.IsEmpty()){

Q.DeQueue(p);

if(p->leftChild!

=NULL){

visit(p->leftChild);

Q.EnQueue(p->leftChild);

}

if(p->rightChild!

=NULL){

visit(p->rightChild);

Q.EnQueue(p->rightChild);

}

}

}

3.6栈结构

3.6.1功能原理

运用栈结构,在非递归算法中,未输出的数据暂时存入栈中,依据先进后出原则,方便了二叉树的遍历。

3.6.2算法原理

二叉树的结点信息,保存在栈中。

第一个入栈的数据元素保存在栈底,后进栈的在上方,现出栈。

3.6.3具体程序

template

voidLinkedStack:

:

Push(constT&x){

top=newStackNode

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

当前位置:首页 > 经管营销 > 销售营销

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

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