二叉树层次遍历.doc
算法与数据结构设计报告( 2012 / 2013 学年 第 二 学期)题 目: 二叉树的层次遍历 专 业 计算机科学与技术 学 生 姓 名 班 级 学 号 指 导 教 师 指 导 单 位 计算机学院计算机科学与技术系日 期 2013年6月3日 评 分 细 则评分项优秀良好中等差遵守机房规章制度上机时的表现学习态度程序准备情况程序设计能力团队合作精神课题功能实现情况算法设计合理性用户界面设计报告书写认真程度内容详实程度文字表达熟练程度回答问题准确度简 短 评 语教师签名: 年 月 日评分等级备注评分等级有五种:优秀、良好、中等、及格、不及格一、课题名称课程设计题目3: 二叉树的层次遍历二、课题内容和要求设计要求:任意选定一棵至少含有8个结点的二叉树,编程实现:(1)按层次遍历算法遍历该二叉树,并给出遍历结果;(2)利用层次遍历算法显示所有叶结点。(3)具体设计要求: I.用队列存储二叉树结点。 II.算法实现层次遍历。三、需求分析树型结构是一类重要的非线性数据结构,其中二叉树最重要。树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构够可以用树来形象表示。树在计算机领域中也得到了广泛应用,如在编译程序中,可以用树来表示源程序的语法结构。二叉树是一种非线性数据结构,对它进行操作时总需要对每个数据逐一进行操作,这样就存在一个操作顺序问题,由此提出了二叉树的遍历操作问题,所谓遍历二叉树就是按某种顺序访问二叉树中某个结点一次且仅一次的过程,这里的访问可以是输出.比较.更新.查看元素内容等各种操作。本程序要求层次遍历算法遍历一棵至少含有8个结点的二叉树,并给出遍历结果。利用层次遍历算法显示所有叶结点。 【队列部分】 用队列存储二叉树结点。 【层次遍历模块】算法实现层次遍历。并给出遍历结果。【结点访问模块】访问所有叶子结点,并显示所有叶结点。四、概要设计在此说明每个部分的算法设计说明(可以是描述算法的流程图),每个程序中使用的存储结构设计说明(如果指定存储结构请写出该存储结构的定义,如果用面向对象的方法,应该给出类中成员变量和成员函数原型声明)。【主函数流程图】输出所有叶子节点自定义一个二叉树开始输出树高结束输出层次遍历【层次遍历算法】 采用队列存储结点是结合层次遍历二叉树和队列“先进先出”的特点综合考虑的,因为层次遍历即从上到下从左到右依次遍历二叉树结点,而队列恰好可以从上到下从左到右顺序进队然后顺序出队,符合设计的要求。【节点访问模块】 通过寻找结点是否有左孩子或右孩子来实现对于结点是否为叶子结点。再将访问得到的叶子结点输出。五、详细设计【二叉树节点类】struct BTNodeBTNode() lChild=rChild=NULL;BTNode(const T& x)element=x; lChild=rChild=NULL;BTNode(const T& x,BTNode<T>* l,BTNode<T>* r)element=x; lChild=l; rChild=r;T element;BTNode<T>* lChild,*rChild; 【二叉树类】 class BinaryTreepublic:static int total;BinaryTree() root=NULL; BinaryTree()Clear(root);bool IsEmpty()const;bool Root(T& x)const;void MakeTree(const T& x,BinaryTree<T>& left,BinaryTree<T>& right);void BreakTree(T& x,BinaryTree<T>& left,BinaryTree<T>& right);int Depth();int leaves();BTNode<T> * GetRoot();void Exchange();void InputRoot(BTNode<T> * t);/更好的解决方案void LevelOrder(void (*Visit)(T& x);protected:BTNode<T>* root;private:void Clear(BTNode<T>* &t);int Depth(BTNode<T> * root);void leaves(BTNode<T>* root);int leaves1(BTNode<T> * root);void LevelOrder(void (*Visit)(T& x),BTNode<T>* t);【二叉树的部分运算】Maketree运算void BinaryTree<T>:MakeTree(const T& x,BinaryTree<T>& left,BinaryTree<T>& right)if(root|&left=&right) return;root=new BTNode<T>(x,left.root,right.root);left.root=right.root=NULL;Breaktree运算void BinaryTree<T>:BreakTree(T& x,BinaryTree<T>& left,BinaryTree<T>& right)if(!root|&left=&right|left.root|right.root) return;x=root->element; left.root=root->lChild;right.root=root->rChild;delete root; root=NULL;Root运算bool BinaryTree<T>:Root(T& x)constif(root)x=root->element; return true;else return false;【节点访问】void Visit(T& x)cout<<x<<" "【层次遍历算法】void BinaryTree<T>:LevelOrder(void (*Visit)(T& x)/层次遍历 LevelOrder(Visit,root);template<class T>void BinaryTree<T>:LevelOrder(void (*Visit)(T& x),BTNode<T>* t) const MaxSize=30; BTNode<T>* QMaxSize;/一位数组队列 int front=0,rear=0; BTNode<T>* p; if(t) rear=(rear+1)%MaxSize;/防溢出 Qrear=t; while(front!=rear) front=(front+1)%MaxSize; p=Qfront; /移动头指针向下传递 cout<<p->element<<" " if(p->lChild) /左孩子进队 rear=(rear+1)%MaxSize; Qrear=p->lChild; if(p->rChild) /右孩子进队 rear=(rear+1)%MaxSize; Qrear=p->rChild; 【叶结点数量,叶结点判断】int BinaryTree<T>:leaves() return leaves1(root);template<class T>int BinaryTree<T>:leaves1(BTNode<T> * root) if(!root) return 0; if(!root->lChild) && (!root->rChild)cout<<root->element<<" "return 1; return leaves1(root->lChild)+leaves1(root->rChild);【树高计算】int BinaryTree<T>:Depth(BTNode<T> * root)int h1=0,h2=0;if(!root) return 0;elseh1=Depth(root->lChild);h2=Depth(root->rChild);if(h1>=h2)return h1+1;/返回左右子树较高的elsereturn h2+1;【主函数】void main(void)BinaryTree<char> a,b,x,y,z;y.MakeTree('E',a,b);z.MakeTree('F',a,b);x.MakeTree('C',y,z);y.MakeTree('D',a,b);z.MakeTree('B',y,x);y.MakeTree('A',a,b);x.MakeTree('H',z,y);z.MakeTree('G',y,x);cout<<"层次遍历结果:"<<endl; z.LevelOrder(Visit); cout<<endl<<endl;cout<<"树的高度是:"<<z.Depth()<<endl<<endl;cout<<"是叶子结点,其个数为:"<<z.leaves()<<endl<<endl;六、测试数据及其结果分析建立二叉树 先序遍历:结果:结果分析:实验结果的排序完全正确。客户可以通过该程序对任意二叉树的输入实现对二叉树的层次遍历。程序基本上满足了算法设计要求,但是仍有地方值得提高,仍需完善。 七、调试过程中的问题在写程序的过程中遇到的麻烦不是很多,由于课本上都把最基本的算法写的很清楚,我们只需要去理解,把分散的知识聚拢来,用学过的知识把一个一个的排序恰当的连接起来就能把程序的主要部分写好,再加一修改就可以了,所以这对于我们来说还是比较轻松的一件事,但是在写程序的过程中还是会遇到一些麻烦,那就需要我们的小心谨慎和积极探索的精神了,争取把程序写的更完美。做课程设计使我知道一个道理:编程需要兴趣和实际动手。这应该可以借鉴在老师的教学工作上。创新思维至关重要,这不仅能让我们写出精简的代码,也有助于开发出高效的程序。八、程序设计总结通过本次课程设计,使我对数据结构这门课的认识更进一步,数据结构作为计算机专业的一门必修课,对如何编写好的算法进行了比较深入的阐述,为我们写出正确的,强壮的代码奠定了基础。在做课程设计的过程中,从查阅的相关资料和问题的解决中学到了不少的知识,因此对课本上的知识也有了更深入的了解。这次课使我了解我编程思想和编程技巧,也认识了软件生命周期的各个环境,包括构思、设计、编写、调试、发布、文档化、维护和修订。编程的风格也很重要,同学只关心程序运行的结果,如果我们希望将来从事编程工作,在这一点上该引起足够的重视。我们应当有更加严谨的态度,这样才能出现更为优秀的程序来解决实际问题。