数据结构 二叉树实验报告
- 格式:doc
- 大小:101.00 KB
- 文档页数:11
数据结构二叉树遍历实验报告数据结构二叉树遍历实验报告一、引言本文档旨在详细介绍二叉树遍历的实验过程和结果。
二叉树是一种在计算机科学领域常用的数据结构,通过遍历二叉树可以获取树中的所有节点数据。
本实验将分别介绍前序遍历、中序遍历和后序遍历这三种常见的遍历方法。
二、实验目的本实验的目的是通过实际操作,加深对二叉树遍历方法的理解,并验证这些遍历方法的正确性和效率。
三、实验环境本实验使用的环境如下:●操作系统: Windows 10●开发工具: Visual Studio Code●编程语言: C++四、实验步骤1.创建二叉树数据结构1.1 定义二叉树节点的结构,包含数据和左右子节点指针。
1.2 创建一个二叉树类,包含插入节点、删除节点、查找节点等方法。
1.3 使用已有的数据集构建二叉树,确保树的结构合理。
2.前序遍历前序遍历是先访问根节点,然后递归地遍历左子树和右子树。
2.1 以递归方式实现前序遍历。
2.2 以迭代方式实现前序遍历。
3.中序遍历中序遍历是先遍历左子树,然后访问根节点,最后遍历右子树。
3.1 以递归方式实现中序遍历。
3.2 以迭代方式实现中序遍历。
4.后序遍历后序遍历是先遍历左子树,然后遍历右子树,最后访问根节点。
4.1 以递归方式实现后序遍历。
4.2 以迭代方式实现后序遍历。
五、实验结果1.前序遍历结果:[节点1数据] [节点2数据] [节点4数据] [节点5数据] [节点3数据]2.中序遍历结果:[节点4数据] [节点2数据] [节点5数据] [节点1数据] [节点3数据]3.后序遍历结果:[节点4数据] [节点5数据] [节点2数据] [节点3数据] [节点1数据]六、实验分析通过实验结果可以看出,不同的遍历顺序得到的节点顺序也不同。
前序遍历先访问根节点,中序遍历先遍历左子树,后序遍历先遍历右子树。
根据需要,可以选择合适的遍历方法来处理二叉树的节点数据。
七、结论本实验验证了前序遍历、中序遍历和后序遍历的正确性,并且对比了它们的不同。
数据结构实验报告二叉树数据结构实验报告:二叉树引言:数据结构是计算机科学中的重要基础,它为我们提供了存储和组织数据的方式。
二叉树作为一种常见的数据结构,广泛应用于各个领域。
本次实验旨在通过实践,深入理解二叉树的概念、性质和操作。
一、二叉树的定义与性质1.1 定义二叉树是一种特殊的树结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。
二叉树可以为空树,也可以是由根节点和左右子树组成的非空树。
1.2 基本性质(1)每个节点最多有两个子节点;(2)左子树和右子树是有顺序的,不能颠倒;(3)二叉树的子树仍然是二叉树。
二、二叉树的遍历2.1 前序遍历前序遍历是指首先访问根节点,然后按照先左后右的顺序遍历左右子树。
在实际应用中,前序遍历常用于复制一颗二叉树或创建二叉树的副本。
2.2 中序遍历中序遍历是指按照先左后根再右的顺序遍历二叉树。
中序遍历的结果是一个有序序列,因此在二叉搜索树中特别有用。
2.3 后序遍历后序遍历是指按照先左后右再根的顺序遍历二叉树。
后序遍历常用于计算二叉树的表达式或释放二叉树的内存。
三、二叉树的实现与应用3.1 二叉树的存储结构二叉树的存储可以使用链式存储或顺序存储。
链式存储使用节点指针连接各个节点,而顺序存储则使用数组来表示二叉树。
3.2 二叉树的应用(1)二叉搜索树:二叉搜索树是一种特殊的二叉树,它的左子树上的节点都小于根节点,右子树上的节点都大于根节点。
二叉搜索树常用于实现查找、插入和删除等操作。
(2)堆:堆是一种特殊的二叉树,它满足堆序性质。
堆常用于实现优先队列,如操作系统中的进程调度。
(3)哈夫曼树:哈夫曼树是一种带权路径最短的二叉树,常用于数据压缩和编码。
四、实验结果与总结通过本次实验,我成功实现了二叉树的基本操作,包括创建二叉树、遍历二叉树和查找节点等。
在实践中,我进一步理解了二叉树的定义、性质和应用。
二叉树作为一种重要的数据结构,在计算机科学中有着广泛的应用,对于提高算法效率和解决实际问题具有重要意义。
实验报告课程名称:数据结构
第 1 页共4 页
五、实验总结(包括心得体会、问题回答及实验改进意见,可附页)
这次实验主要是建立二叉树,和二叉树的先序、中序、后续遍历算法。
通过这次实验,我巩固了二叉树这部分知识,从中体会理论知识的重要性。
在做实验之前,要充分的理解本次实验的理论依据,这样才能达到事半功倍的效果。
如果在没有真正理解实验原理之盲目的开始实验,只会浪费时间和精力。
例如进行二叉树的遍历的时候,要先理解各种遍历的特点。
先序遍历是先遍历根节点,再依次先序遍历左右子树。
中序遍历是先中序遍历左子树,再访问根节点,最后中序遍历右子树。
而后序遍历则是先依次后续遍历左右子树,再访问根节点。
掌握了这些,在实验中我们就可以融会贯通,举一反三。
其次要根据不光要懂得代码的原理,还要对题目有深刻的了解,要明白二叉树的画法,在纸上先进行自我演练,对照代码验证自己写的正确性。
第 3 页共4 页
第 4 页共4 页。
数据结构实验报告二叉树《数据结构与算法》实验报告专业班级姓名学号实验项目实验三二叉树。
实验目的1、掌握用递归方法实现二叉树的遍历。
2、加深对二叉树的理解,逐步培养解决实际问题的编程能力。
题目:(1)编写二叉树的遍历操作函数。
①先序遍历,递归方法re_preOrder(TREE *tree)②中序遍历,递归方法re_midOrder(TREE *tree)③后序遍历,递归方法re_postOrder(TREE *tree)(2)调用上述函数实现先序、中序和后序遍历二叉树操作。
算法设计分析(一)数据结构的定义要求用c语言编写一个演示程序,首先建立一个二叉树,让用户输入一个二叉树,实现该二叉树的便利操作。
二叉树型存储结构定义为:typedef struct TNode{ char data;//字符型数据struct TNode *lchild,*rchild;//左右孩子指针}TNode,* Tree;(二)总体设计程序由主函数、二叉树建立函数、先序遍历函数、中序遍历函数、后序遍历函数五个函数组成。
其功能描述如下:(1)主函数:统筹调用各个函数以实现相应功能。
int main()(2)二叉树建立函数:根据用户意愿运用先序遍历建立一个二叉树。
int CreateBiTree(Tree &T)(3)先序遍历函数:将所建立的二叉树先序遍历输出。
void PreOrder(Tree T)(4)中序遍历函数:将所建立的二叉树中序遍历输出。
void InOrder(Tree T)(5)后序遍历函数:将所建立的二叉树后序遍历输出。
void PostOrder(Tree T)(三)各函数的详细设计:(1)建立一个二叉树,按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树。
对T动态分配存储空间,生成根节点,构造左、右子树(2)编写先序遍历函数,依次访问根节点、左子结点、右子节点(3)编写中序遍历函数,依次访问左子结点、根节点、右子节点(4)编写后序遍历函数,依次访问左子结点、右子节点、根节点(5)编写主函数,调用各个函数,以实现二叉树遍历的基本操作。
数据结构二叉树的实验报告数据结构二叉树的实验报告一、引言数据结构是计算机科学中非常重要的一个领域,它研究如何组织和存储数据以便高效地访问和操作。
二叉树是数据结构中常见且重要的一种,它具有良好的灵活性和高效性,被广泛应用于各种领域。
本实验旨在通过实际操作和观察,深入了解二叉树的特性和应用。
二、实验目的1. 理解二叉树的基本概念和特性;2. 掌握二叉树的创建、遍历和查找等基本操作;3. 通过实验验证二叉树的性能和效果。
三、实验过程1. 二叉树的创建在实验中,我们首先需要创建一个二叉树。
通过输入一系列数据,我们可以按照特定的规则构建一棵二叉树。
例如,可以按照从小到大或从大到小的顺序将数据插入到二叉树中,以保证树的有序性。
2. 二叉树的遍历二叉树的遍历是指按照一定的次序访问二叉树中的所有节点。
常见的遍历方式有前序遍历、中序遍历和后序遍历。
前序遍历是先访问根节点,然后再依次遍历左子树和右子树;中序遍历是先遍历左子树,然后访问根节点,最后再遍历右子树;后序遍历是先遍历左子树,然后遍历右子树,最后访问根节点。
3. 二叉树的查找二叉树的查找是指在二叉树中寻找指定的节点。
常见的查找方式有深度优先搜索和广度优先搜索。
深度优先搜索是从根节点开始,沿着左子树一直向下搜索,直到找到目标节点或者到达叶子节点;广度优先搜索是从根节点开始,逐层遍历二叉树,直到找到目标节点或者遍历完所有节点。
四、实验结果通过实验,我们可以观察到二叉树的特性和性能。
在创建二叉树时,如果按照有序的方式插入数据,可以得到一棵平衡二叉树,其查找效率较高。
而如果按照无序的方式插入数据,可能得到一棵不平衡的二叉树,其查找效率较低。
在遍历二叉树时,不同的遍历方式会得到不同的结果。
前序遍历可以用于复制一棵二叉树,中序遍历可以用于对二叉树进行排序,后序遍历可以用于释放二叉树的内存。
在查找二叉树时,深度优先搜索和广度优先搜索各有优劣。
深度优先搜索在空间复杂度上较低,但可能会陷入死循环;广度优先搜索在时间复杂度上较低,但需要较大的空间开销。
数据结构实验报告—二叉树数据结构实验报告—二叉树引言二叉树是一种常用的数据结构,它由节点和边构成,每个节点最多有两个子节点。
在本次实验中,我们将对二叉树的基本结构和基本操作进行实现和测试,并深入了解它的特性和应用。
实验目的1. 掌握二叉树的基本概念和特性2. 熟练掌握二叉树的基本操作,包括创建、遍历和查找等3. 了解二叉树在实际应用中的使用场景实验内容1. 二叉树的定义和存储结构:我们将首先学习二叉树的定义,并实现二叉树的存储结构,包括节点的定义和节点指针的表示方法。
2. 二叉树的创建和初始化:我们将实现二叉树的创建和初始化操作,以便后续操作和测试使用。
3. 二叉树的遍历:我们将实现二叉树的前序、中序和后序遍历算法,并测试其正确性和效率。
4. 二叉树的查找:我们将实现二叉树的查找操作,包括查找节点和查找最大值、最小值等。
5. 二叉树的应用:我们将探讨二叉树在实际应用中的使用场景,如哈夫曼编码、二叉搜索树等。
二叉树的定义和存储结构二叉树是一种特殊的树形结构,它的每个节点最多有两个子节点。
节点被表示为一个由数据和指向其左右子节点的指针组成的结构。
二叉树可以分为三类:满二叉树、完全二叉树和非完全二叉树。
二叉树可以用链式存储结构或顺序存储结构表示。
- 链式存储结构:采用节点定义和指针表示法,通过将节点起来形成一个树状结构来表示二叉树。
- 顺序存储结构:采用数组存储节点信息,通过计算节点在数组中的位置来进行访问和操作。
二叉树的创建和初始化二叉树的创建和初始化是二叉树操作中的基础部分。
我们可以通过手动输入或读取外部文件中的数据来创建二叉树。
对于链式存储结构,我们需要自定义节点和指针,并通过节点的方式来构建二叉树。
对于顺序存储结构,我们需要定义数组和索引,通过索引计算来定位节点的位置。
一般来说,初始化一个二叉树可以使用以下步骤:1. 创建树根节点,并赋初值。
2. 创建子节点,并到父节点。
3. 重复步骤2,直到创建完整个二叉树。
数据结构实验报告1. 实验目的和内容:掌握二叉树基本操作的实现方法2. 程序分析2.1存储结构链式存储2.程序流程2.3关键算法分析算法一:Create(BiNode<T>* &R,T data[],int i,int n)【1】算法功能:创建二叉树【2】算法基本思想:利用顺序存储结构为输入,采用先建立根结点,再建立左右孩子的方法来递归建立二叉链表的二叉树【3】算法空间时间复杂度分析:O(n)【4】代码逻辑:如果位置小于数组的长度则{ 创建根结点将数组的值赋给刚才创建的结点的数据域创建左子树,如果当前结点位置为i,则左孩子位置为2i创建右子树,如果当前结点位置为i,则右孩子位置为2i+1}否则R为空算法二:CopyTree(BiNode<T>*sR,BiNode<T>* &dR))【1】算法功能:复制构造函数【2】算法基本思想:按照先创建根结点,再递归创建左右子树的方法来实现。
【3】算法空间时间复杂度分析:O(n)【4】代码逻辑:如果源二叉树根结点不为空则{创建根结点调用函数自身,创建左子树调用函数自身,创建右子树}将该函数放在复制构造函数中调用,就可以实现复制构造函数算法三:PreOrder(BiNode<T>*R)【1】算法功能:二叉树的前序遍历【2】算法基本思想:这个代码用的是优化算法,提前让当前结点出栈。
【3】算法空间时间复杂度分析:O(n)【4】代码逻辑(伪代码)如果当前结点为非空,则{访问当前结点当前结点入栈将当前结点的左孩子作为当前结点}如果为空{则栈顶结点出栈则将该结点的右孩子作为当前结点}反复执行这两个过程,直到结点为空并且栈空算法四:InOrder(BiNode<T>*R)【1】算法功能:二叉树的中序遍历【2】算法基本思想:递归【3】算法空间时间复杂度分析:未知【4】代码逻辑:如果R为非空:则调用函数自身遍历左孩子访问该结点再调用自身访问该结点的右孩子算法五:LevelOrder(BiNode<T>*R)【1】算法功能:二叉树的层序遍历【2】算法基本思想:【3】算法空间时间复杂度分析:O(n)【4】代码逻辑(伪代码):如果队列不空{对头元素出队访问该元素若该结点的左孩子为非空,则左孩子入队;若该结点的右孩子为非空,则右孩子入队;}算法六:Count(BiNode<T>*R)【1】算法功能:计算结点的个数【2】算法基本思想:递归【3】算法空间时间复杂度分析:未知【4】代码逻辑:如果R不为空的话{调用函数自身计算左孩子的结点数调用函数自身计算右孩子的结点数}template<class T>int BiTree<T>::Count(BiNode<T>*R){if(R==NULL)return 0;else{int m=Count(R->lchild);int n=Count(R->rchild);return m+n+1;}}算法七:Release(BiNode<T>*R)【1】算法功能:释放动态内存【2】算法基本思想:左右子树全部释放完毕后再释放该结点【3】算法空间时间复杂度分析:未知【4】代码逻辑:调用函数自身,释放左子树调用函数自身,释放右子树释放根结点释放二叉树template<class T>void BiTree<T>::Release(BiNode<T>*R) {if(R!=NULL){Release(R->lchild);Release(R->rchild);delete R;}}template<class T>BiTree<T>::~BiTree(){Release(root);}int main(){BiTree<int> BTree(a,10);BiTree<int>Tree(BTree);BTree.PreOrder(BTree.root);cout<<endl;Tree.PreOrder(Tree.root);cout<<endl;BTree.InOrder(BTree.root);cout<<endl;Tree.InOrder(Tree.root);cout<<endl;BTree.PostOrder(BTree.root);cout<<endl;Tree.PostOrder(Tree.root);cout<<endl;BTree.LevelOrder(BTree.root);cout<<endl;Tree.LevelOrder(Tree.root);cout<<endl;int m=BTree.Count(BTree.root);cout<<m<<endl;return 0;}3.测试数据:int a[10]={1,2,3,4,5};1 2 4 5 31 2 4 5 34 25 1 34 5 2 3 11 2 3 4 554.总结:4.1:这次实验大多用了递归的算法,比较好理解。
实验5:树(二叉树)(采用二叉链表存储)一、实验项目名称二叉树及其应用二、实验目的熟悉二叉树的存储结构的特性以及二叉树的基本操作。
三、实验基本原理之前我们都是学习的线性结构,这次我们就开始学习非线性结构——树。
线性结构中结点间具有唯一前驱、唯一后继关系,而非线性结构中结点的前驱、后继的关系并不具有唯一性。
在树结构中,节点间关系是前驱唯一而后继不唯一,即结点之间是一对多的关系。
直观地看,树结构是具有分支关系的结构(其分叉、分层的特征类似于自然界中的树)。
四、主要仪器设备及耗材Window 11、Dev-C++5.11五、实验步骤1.导入库和预定义2.创建二叉树3.前序遍历4.中序遍历5.后序遍历6.总结点数7.叶子节点数8.树的深度9.树根到叶子的最长路径10.交换所有节点的左右子女11.顺序存储12.显示顺序存储13.测试函数和主函数对二叉树的每一个操作写测试函数,然后在主函数用while+switch-case的方式实现一个带菜单的简易测试程序,代码见“实验完整代码”。
实验完整代码:#include <bits/stdc++.h>using namespace std;#define MAX_TREE_SIZE 100typedef char ElemType;ElemType SqBiTree[MAX_TREE_SIZE];struct BiTNode{ElemType data;BiTNode *l,*r;}*T;void createBiTree(BiTNode *&T){ElemType e;e = getchar();if(e == '\n')return;else if(e == ' ')T = NULL;else{if(!(T = (BiTNode *)malloc(sizeof (BiTNode)))){cout << "内存分配错误!" << endl;exit(0);}T->data = e;createBiTree(T->l);createBiTree(T->r);}}void createBiTree2(BiTNode *T,int u) {if(T){SqBiTree[u] = T->data;createBiTree2(T->l,2 * u + 1);createBiTree2(T->r,2 * u + 2); }}void outputBiTree2(int n){int cnt = 0;for(int i = 0;cnt <= n;i++){cout << SqBiTree[i];if(SqBiTree[i] != ' ')cnt ++;}cout << endl;}void preOrderTraverse(BiTNode *T) {if(T){cout << T->data;preOrderTraverse(T->l);preOrderTraverse(T->r);}}void inOrderTraverse(BiTNode *T) {if(T){inOrderTraverse(T->l);cout << T->data;inOrderTraverse(T->r);}}void beOrderTraverse(BiTNode *T){if(T){beOrderTraverse(T->l);beOrderTraverse(T->r);cout << T->data;}}int sumOfVer(BiTNode *T){if(!T)return 0;return sumOfVer(T->l) + sumOfVer(T->r) + 1;}int sumOfLeaf(BiTNode *T){if(!T)return 0;if(T->l == NULL && T->r == NULL)return 1;return sumOfLeaf(T->l) + sumOfLeaf(T->r);}int depth(BiTNode *T){if(!T)return 0;return max(depth(T->l),depth(T->r)) + 1;}bool LongestPath(int dist,int dist2,vector<ElemType> &ne,BiTNode *T) {if(!T)return false;if(dist2 == dist)return true;if(LongestPath(dist,dist2 + 1,ne,T->l)){ne.push_back(T->l->data);return true;}else if(LongestPath(dist,dist2 + 1,ne,T->r)){ne.push_back(T->r->data);return true;}return false;}void swapVer(BiTNode *&T){if(T){swapVer(T->l);swapVer(T->r);BiTNode *tmp = T->l;T->l = T->r;T->r = tmp;}}//以下是测试程序void test1(){getchar();cout << "请以先序次序输入二叉树结点的值,空结点用空格表示:" << endl; createBiTree(T);cout << "二叉树创建成功!" << endl;}void test2(){cout << "二叉树的前序遍历为:" << endl;preOrderTraverse(T);cout << endl;}void test3(){cout << "二叉树的中序遍历为:" << endl;inOrderTraverse(T);cout << endl;}void test4(){cout << "二叉树的后序遍历为:" << endl;beOrderTraverse(T);cout << endl;}void test5(){cout << "二叉树的总结点数为:" << sumOfVer(T) << endl;}void test6(){cout << "二叉树的叶子结点数为:" << sumOfLeaf(T) << endl; }void test7(){cout << "二叉树的深度为:" << depth(T) << endl;}void test8(){int dist = depth(T);vector<ElemType> ne;cout << "树根到叶子的最长路径:" << endl;LongestPath(dist,1,ne,T);ne.push_back(T->data);reverse(ne.begin(),ne.end());cout << ne[0];for(int i = 1;i < ne.size();i++)cout << "->" << ne[i];cout << endl;}void test9(){swapVer(T);cout << "操作成功!" << endl;}void test10(){memset(SqBiTree,' ',sizeof SqBiTree);createBiTree2(T,0);cout << "操作成功!" << endl;}void test11(){int n = sumOfVer(T);outputBiTree2(n);}int main(){int op = 0;while(op != 12){cout << "-----------------menu--------------------" << endl;cout << "--------------1:创建二叉树--------------" << endl;cout << "--------------2:前序遍历----------------" << endl;cout << "--------------3:中序遍历----------------" << endl;cout << "--------------4:后序遍历----------------" << endl;cout << "--------------5:总结点数----------------" << endl;cout << "--------------6:叶子节点数--------------" << endl;cout << "--------------7:树的深度----------------" << endl;cout << "--------------8:树根到叶子的最长路径----" << endl;cout << "--------------9:交换所有节点左右子女----" << endl;cout << "--------------10:顺序存储---------------" << endl;cout << "--------------11:显示顺序存储-----------" << endl;cout << "--------------12:退出测试程序-----------" << endl;cout << "请输入指令编号:" << endl;if(!(cin >> op)){cin.clear();cin.ignore(INT_MAX,'\n');cout << "请输入整数!" << endl;continue;}switch(op){case 1:test1();break;case 2:test2();break;case 3:test3();break;case 4:test4();break;case 5:test5();break;case 6:test6();break;case 7:test7();break;case 8:test8();break;case 9:test9();break;case 10:test10();break;case 11:test11();break;case 12:cout << "测试结束!" << endl;break;default:cout << "请输入正确的指令编号!" << endl;}}return 0;}六、实验数据及处理结果测试用例:1.创建二叉树(二叉链表形式)2.前序遍历3.中序遍历4.后序遍历5.总结点数6.叶子结点数7.树的深度8.树根到叶子的最长路径9.交换所有左右子女10.顺序存储七、思考讨论题或体会或对改进实验的建议通过这次实验,我掌握了二叉树的顺序存储和链式存储,体会了二叉树的存储结构的特性,掌握了二叉树的树上相关操作。
一、需求分析:编写一段程序,对二叉树进行复合操作,包括创建一棵二叉树,显示二叉树的树型结构,对创建的二叉树进行先根、中根、后根三种方式进行遍历,并且打印出叶子结点,并且可以随时删除我们创建的二叉树,然后用循环语句将上述的操作封装起来,使之能够进行可重复、连续的操作。
输入为a-z或者是A-Z之间的字符,用‘@’字符作为结束当前结点的标识符。
二、概要设计:本程序要用到的数据类型struct BinTreeNode{ DataType info;PBinTreeNode llink;PBinTreeNode rlink;};然后定义我们需要的指针类型typedef struct BinTreeNode *PBinTreeNode; /* 定义指向二叉树结点的指针类型*/typedef PBinTreeNode *PBinTree; /*定义指向树型结点的指针类型*/程序需要用到的自定义函数1.创建一个二叉树根节点PBinTree Create_BinTreeRoot(void)2.创建一个二叉树的节点PBinTreeNode Create_BinTreeNode(void)3.创建一棵二叉树PBinTreeNode Create_BinTree(void)4.用先根的方法遍历一棵二叉树void preOrder(PBinTreeNode pbnode)5.用中根的方法遍历一棵二叉树void inOrder(PBinTreeNode pbnode)6.用后根的方法遍历一棵二叉树void postOrder(PBinTreeNode pbnode)7.打印出我们创建的二叉树的树型结构void outputTree(PBinTreeNode pbnode,int totalSpace)8.打印出二叉树的叶子结点void leaves(PBinTreeNode pbnode)9.释放我们所申请的所有结点空间void freeAllNodes(PBinTreeNode pbnode)10.判断我们输入的是否是合格的字符int isalphabet(char i)三、详细设计:1.PBinTreeNode Create_BinTreeNode(void)我们定义一个指向二叉树结点类型的指针PBinTreeNode,然后,申请一个二叉树结点大小的空间,对左右子结点赋为空。
2.创建一个二叉树根节点定义一个指向二叉树结点的指针的指针即:BinTreeNode ** pbtree, 或者是:PBinTreeNode *pbtree;用于存放树的根结点,同时,将我们创建的二叉树的地址传给它即:*pbtree=Create_BinTree();3.创建一棵二叉树首先我们定义一个DataType类型的变量i,用于存放我们输入的字符(即作为缓冲区),并用scanf函数去接收它,由于使用scanf函数时,会出现吸收我们输入的回车字符,并将会车作为接收的字符的情况发生,为了避免这种情况,我们用函数fflush(stdin)将缓冲区的字符全部冲掉,然后再吸收我们输入的字符,就可以完全避免此类问题的发生。
我们定义我们输入的字符是从a-z或者是A-Z,用字符@为我们结束当前结点左或者右结点的字符,然后递归调用左右子树,此时我们将一棵二叉树全整的创建出来了。
4.用先根的方法遍历一棵二叉树先访问根结点,打印出它里面的信息,然后递归调用左子树和右子树。
5.用中根的方法遍历一棵二叉树先递归调用左子树,打印出里面的信息,在打印出根结点信息,然后递归调用右子树,打印出里面的信息。
6.用后根的方法遍历一棵二叉树先递归调用左子树,打印出里面的内容,然后递归调用右子树,打印出里面的内容,然后是根结点的内容。
7. 打印出我们创建的二叉树的树型结构先递归调用右子树,如果结点不为空的话,空格数加5,如果为空的话,就打印出右子树的内容,然后递归调用左子树。
8.打印出二叉树的叶子结点如果当前结点的左右子树都为空的话,就打印出此结点的信息,如果左子树不为空的话,递归调用左子树,如果右子树不为空的话,递归调用右子树。
9.释放我们所申请的所有结点空间如果当前的左子树不为空,则遍历左子树,如果右子树不为空的话,则遍历右子树,如果都不位空的话,分别调用左右子树,如果左右都为空的话,就释放左右结点空间,并将当前结点置为空。
10.主函数的安排:先创建好我们要的二叉树,之后,我们就可以对此而二树进行多种操作,我们定义了6种集合操作,并对用户输入的信息进行检测,正确的提示出错信息,如果选择的是我们定义的操作之一的话,对应的我们设置出不同的case语句。
如果我们选择的是释放所有的结点空间的话,我们需要屏蔽掉所有的菜单信息,提示用户重新创建一棵二叉树,并对它进行重新操作。
如果我们选择退出,但是没有选择释放掉所有的节点空间时,我们需要考虑到此类的情形,应调用void freeAllNodes(PBinTreeNode pbnode)自动的释放掉所有的结点空间,正常的退出。
四、用户使用说明:当用户还没有创建二叉树时,提示用户输入数据:Please input char to the binatree, @ to exit current node:Please input a char:这时用户用键盘输入,每输入一个字符回车一次,输入为a-z或者是A-Z之间的字符,用‘@’字符作为结束当前结点的标识符当用户,创建了二叉树之后,出现控制菜单:Please choose the mode you want to operate with the binatree:1.display2.preOrder3.inOrder4.postOrder5.leaves6.free nodes 0 to exit:此时用户可以选择操作:1. 自动的打印出树型结构2.先根遍历3.中根遍历4.后根遍历5. 打印叶子结点6. 释放所有结点空间0.退出五、测试结果:1.测试完全二叉树的情形:输入(每输入一个字符回车一次):A B C @ @ D @ @ E F @ @ G @ @自动的打印出树型结构:Display the binatree data directly:GEFADBC三种遍历方式和叶子结点,测试如下:先根:Data in preOrder:A B C D E F G中根:Data in inOrder:C BD A FE G后根:Data in postOrder:C D B F G E A打印叶子结点:Leaves:C D F G释放所有结点空间:Free all nodes:All node have been freed successfully.自动提示创建一棵新的二叉树:Now creating a new binatree...Please input char to the binatree, @ to exit current node:Please input a char:2测试非完全二叉树的情形输入(每输入一个字符回车一次):A B C D @ @ @ @ @自动的打印出树型结构:ABCD三种遍历方式和叶子结点,测试如下:先根:Data in preOrder:A B C D中根:Data in inOrder:D C B A后根:Data in postOrder:D C B A打印叶子结点:Leaves:D释放所有结点空间:Free all nodes:All node have been freed successfully.自动提示创建一棵新的二叉树:Now creating a new binatree...Please input char to the binatree, @ to exit current node:Please input a char:如果我们想结束此次的操作,退出本程序,就可以输入0,程序自动的释放所有的结点空间:Please choose the mode you want to operate with the binatree:1.display2.preOrder3.inOrder4.postOrder5.leaves6.free nodes 0 to exit:0Dealing with the last job, to free all nodesAll node have been freed successfully六、附录:#include <stdio.h>#include <stdlib.h>#include <conio.h>#define NULL 0#define DataType chartypedef struct BinTreeNode *PBinTreeNode;typedef PBinTreeNode *PBinTree;struct BinTreeNode{ DataType info;PBinTreeNode llink;PBinTreeNode rlink;};PBinTreeNode Create_BinTree(void);PBinTree Create_BinTreeRoot(void){PBinTree pbtree;pbtree=(PBinTree)malloc(sizeof(struct BinTreeNode));if(pbtree==NULL) pbtree=(PBinTree)realloc(pbtree,sizeof(struct BinTreeNode));*pbtree=Create_BinTree();return (pbtree);}PBinTreeNode Create_BinTreeNode(void){PBinTreeNode pbnode;pbnode=(PBinTreeNode)malloc(sizeof(struct BinTreeNode));if(pbnode==NULL) pbnode=(PBinTreeNode)realloc(pbnode,sizeof(struct BinTreeNode)); else pbnode->llink=pbnode->rlink=(PBinTreeNode)NULL;return (pbnode);}int isalphabet(char i){if (i >= 'a' && i <='z' || i >= 'A' && i <='Z' || i=='@')return 1;else return 0;}PBinTreeNode Create_BinTree(void){PBinTreeNode pbnode ;DataType i;printf("Please input a char:\t");fflush(stdin);scanf("%c",&i);fflush(stdin);while(!isalphabet(i)){printf("Sorry, your input char is not in alphabet, please input again:");scanf("%c",&i);fflush(stdin);}if(i=='@') pbnode= NULL;else{pbnode = (PBinTreeNode)malloc(sizeof(struct BinTreeNode));if(pbnode == NULL){printf("Out of space!\n");return pbnode ;}pbnode->info=i;pbnode->llink=Create_BinTree();pbnode->rlink=Create_BinTree();}return pbnode;}void outputTree(PBinTreeNode pbnode,int totalSpace){int i;if(pbnode!=NULL){totalSpace+=5;outputTree(pbnode->rlink,totalSpace);for(i=0;i<totalSpace;i++) printf(" ");printf("%c\n",pbnode->info);outputTree(pbnode->llink,totalSpace);}}void preOrder(PBinTreeNode pbnode){if(pbnode==NULL) return ;printf("%c\t",pbnode->info);preOrder(pbnode->llink);preOrder(pbnode->rlink);}void inOrder(PBinTreeNode pbnode){if(pbnode== NULL) return;inOrder(pbnode->llink);printf("%c\t",pbnode->info);inOrder(pbnode->rlink);}void postOrder(PBinTreeNode pbnode){if(pbnode == NULL) return ;postOrder(pbnode->llink);postOrder(pbnode->rlink);printf("%c\t", pbnode->info);}void leaves(PBinTreeNode pbnode){if(pbnode->llink != NULL && pbnode->rlink == NULL) leaves(pbnode->llink);if(pbnode->rlink != NULL && pbnode->llink == NULL) leaves(pbnode->rlink);if(pbnode->llink != NULL && pbnode->rlink != NULL) {leaves(pbnode->llink);leaves(pbnode->rlink);}if(pbnode->llink == NULL && pbnode->rlink == NULL) {printf("%c\t",pbnode->info);return;}}void freeAllNodes(PBinTreeNode pbnode){if(pbnode->llink != NULL && pbnode->rlink == NULL) freeAllNodes(pbnode->llink);if(pbnode->rlink != NULL && pbnode->llink == NULL) freeAllNodes(pbnode->rlink);if(pbnode->llink != NULL && pbnode->rlink != NULL){freeAllNodes(pbnode->llink);freeAllNodes(pbnode->rlink);}if(pbnode->llink == NULL && pbnode->rlink == NULL){free(pbnode->llink);free(pbnode->rlink);pbnode = NULL;return ;}}int main(){PBinTree pbtree;int i;int totalSpace = 0;printf("Please input char to the binatree,@ to exit current node:\n");pbtree = Create_BinTreeRoot();printf("Display the binatree data directly:\n");outputTree(*pbtree,totalSpace);printf("Please choose the mode you want to operate with the binatree:\n");printf("1.display 2.preOrder 3.inOrder 4.postOrder 5.leaves 6.free nodes 0 to exit:");scanf("%d",&i);while(i>6 || i<0){printf("\nYou choice is illegal please input again:\n");printf("1.display 2.preOrder 3.inOrder 4.postOrder 5.leaves 6.free nodes 0 to exit:");scanf("%d",&i);}while(i!=0){while(i > 6 || i<0){printf("\nYou choice is illegal please input again:\n");printf("1.display 2.preOrder 3.inOrder 4.postOrder 5.leaves 6.free nodes 0 to exit:");scanf("%d",&i);}while(i !=0){while(i > 6 || i<0){printf("\nYou choice is illegal please input again:\n");printf("1.display 2.preOrder 3.inOrder 4.postOrder 5.leaves 6.free nodes 0 to exit:");scanf("%d",&i);}while(i !=6){while(i > 6 || i<0){printf("\nYou choice is illegal please input again:\n");printf("1.display 2.preOrder 3.inOrder 4.postOrder 5.leaves 6.free nodes 0 to exit:");scanf("%d",&i);}switch(i){case 0 :printf("\nDealing with the last job, to free all nodes...\n");freeAllNodes(*pbtree);printf("All node have been freed successfully\n");exit(1);getch();case 1 :printf("\nDisplay binatree:\n");outputTree(*pbtree,totalSpace);break;case 2 :printf("\nData in preOrder:\n");preOrder(*pbtree);printf("\n\n");break;case 3 :printf("\nData in inOrder:\n");inOrder(*pbtree);printf("\n\n");break;case 4 :printf("\nData in postOrder:\n");postOrder(*pbtree);printf("\n\n");break;case 5:printf("\nLeaves:\n");leaves(*pbtree);printf("\n\n");}printf("Please choose the mode you want to operate with the binatree:\n");printf("1.display 2.preOrder 3.inOrder 4.postOrder 5.leaves 6.free nodes 0 to exit:");scanf("%d",&i);}if(i==6){printf("\nFree all nodes:\n");freeAllNodes(*pbtree);printf("All node have been freed successfully.");}printf("\n\nNow creating a new binatree...\n");printf("Please input char to the binatree,@ to exit current node:\n");pbtree = Create_BinTreeRoot();printf("Display the binatree data directly:\n");outputTree(*pbtree,totalSpace);printf("Please choose the mode you want to operate with the binatree:\n");printf("1.display 2.preOrder 3.inOrder 4.postOrder 5.leaves 6.free nodes 0 to exit:");scanf("%d",&i);}}printf("\nDealing with the last job, to free all nodes\n");freeAllNodes(*pbtree);printf("All node have been freed successfully\n");getch();return 0;}七.图形界面根据提示一步步进行操作。