数据结构二叉树实验
- 格式:docx
- 大小:387.80 KB
- 文档页数:56
数据结构二叉树遍历实验报告一、实验目的本次实验的主要目的是深入理解和掌握二叉树的三种遍历方式:前序遍历、中序遍历和后序遍历,并通过实际编程实现来加深对这些遍历算法的理解和应用能力。
二、实验环境本次实验使用的编程语言为 Python,开发工具为 PyCharm。
三、实验原理1、二叉树的定义二叉树是一种每个节点最多有两个子节点的树结构,分别称为左子节点和右子节点。
2、前序遍历前序遍历首先访问根节点,然后递归地前序遍历左子树,最后递归地前序遍历右子树。
3、中序遍历中序遍历首先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。
4、后序遍历后序遍历首先递归地后序遍历左子树,然后递归地后序遍历右子树,最后访问根节点。
四、实验步骤1、定义二叉树节点类```pythonclass TreeNode:def __init__(self, value):selfvalue = valueselfleft = Noneselfright = None```2、实现前序遍历函数```pythondef pre_order_traversal(root):if root is not None:print(rootvalue, end="")pre_order_traversal(rootleft)pre_order_traversal(rootright)```3、实现中序遍历函数```pythondef in_order_traversal(root):if root is not None:in_order_traversal(rootleft) print(rootvalue, end="")in_order_traversal(rootright)```4、实现后序遍历函数```pythondef post_order_traversal(root):if root is not None:post_order_traversal(rootleft) post_order_traversal(rootright) print(rootvalue, end="")```5、构建二叉树并进行遍历```python构建二叉树root = TreeNode(1) rootleft = TreeNode(2) rootright = TreeNode(3) rootleftleft = TreeNode(4) rootleftright = TreeNode(5)前序遍历print("前序遍历:")pre_order_traversal(root) print()中序遍历print("中序遍历:")in_order_traversal(root) print()后序遍历print("后序遍历:")post_order_traversal(root)print()```五、实验结果1、前序遍历结果:1 2 4 5 32、中序遍历结果:4 2 5 1 33、后序遍历结果:4 5 2 3 1六、结果分析1、前序遍历在前序遍历中,首先访问根节点,然后再访问左子树和右子树。
华科数据结构二叉树实验报告一、实验目的本实验旨在通过实践操作,加深对数据结构中二叉树的理解,掌握二叉树的基本操作和应用。
二、实验内容1. 实现二叉树的创建和初始化。
2. 实现二叉树的插入操作。
3. 实现二叉树的删除操作。
4. 实现二叉树的查找操作。
5. 实现二叉树的遍历操作:前序遍历、中序遍历、后序遍历。
6. 实现二叉树的层次遍历。
7. 实现二叉树的销毁操作。
8. 进行实验测试,并分析实验结果。
三、实验步骤1. 创建二叉树的数据结构,包括节点的定义和指针的初始化。
2. 实现二叉树的创建和初始化函数,根据给定的数据构建二叉树。
3. 实现二叉树的插入操作函数,将新节点插入到二叉树的合适位置。
4. 实现二叉树的删除操作函数,删除指定节点,并保持二叉树的结构完整。
5. 实现二叉树的查找操作函数,根据给定的值查找对应的节点。
6. 实现二叉树的遍历操作函数,包括前序遍历、中序遍历、后序遍历。
7. 实现二叉树的层次遍历函数,按照层次顺序遍历二叉树。
8. 实现二叉树的销毁操作函数,释放二叉树的内存空间。
9. 编写测试程序,对上述函数进行测试,并分析实验结果。
四、实验结果与分析经过测试,实验结果如下:1. 创建和初始化函数能够正确构建二叉树,并初始化节点的值和指针。
2. 插入操作函数能够将新节点插入到二叉树的合适位置,并保持二叉树的结构完整。
3. 删除操作函数能够正确删除指定节点,并保持二叉树的结构完整。
4. 查找操作函数能够根据给定的值找到对应的节点。
5. 遍历操作函数能够按照指定的顺序遍历二叉树,并输出节点的值。
6. 层次遍历函数能够按照层次顺序遍历二叉树,并输出节点的值。
7. 销毁操作函数能够释放二叉树的内存空间,防止内存泄漏。
根据实验结果分析,二叉树的基本操作和应用都能够正常实现,达到了预期的效果。
五、实验总结通过本次实验,我进一步加深了对数据结构中二叉树的理解,并掌握了二叉树的基本操作和应用。
通过实践操作,我更加熟悉了二叉树的创建、插入、删除、查找和遍历等操作,同时也学会了如何进行层次遍历和销毁二叉树。
数据结构实验报告二叉树数据结构实验报告:二叉树引言:数据结构是计算机科学中的重要基础,它为我们提供了存储和组织数据的方式。
二叉树作为一种常见的数据结构,广泛应用于各个领域。
本次实验旨在通过实践,深入理解二叉树的概念、性质和操作。
一、二叉树的定义与性质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.理解二叉树的性质;3.熟悉二叉树的广度优先遍历和深度优先遍历算法。
二、实验原理:1.二叉树是一种树形结构,由n(n>=0)个节点组成;2.每个节点最多有两个子节点,称为左子节点和右子节点;3.二叉树的遍历分为四种方式:前序遍历、中序遍历、后序遍历和层次遍历。
三、实验环境:1.编程语言:C++;2.编译器:Dev-C++。
四、实验内容:1.定义二叉树节点结构体:struct BinaryTreeNode{int data; // 节点数据BinaryTreeNode *leftChild; // 左子节点指针BinaryTreeNode *rightChild; // 右子节点指针};2.初始化二叉树:queue<BinaryTreeNode *> q; // 使用队列存储节点q.push(root);int i = 1; // 创建子节点while (!q.empty() && i < length){BinaryTreeNode *node = q.front();q.pop();if (data[i] != -1) // 创建左子节点 {BinaryTreeNode *leftChild = new BinaryTreeNode;leftChild->data = data[i];leftChild->leftChild = nullptr;leftChild->rightChild = nullptr;node->leftChild = leftChild;q.push(leftChild);}i++;if (data[i] != -1) // 创建右子节点 {BinaryTreeNode *rightChild = new BinaryTreeNode;rightChild->data = data[i];rightChild->leftChild = nullptr;rightChild->rightChild = nullptr;node->rightChild = rightChild;q.push(rightChild);}i++;}return root;}3.前序遍历二叉树:五、实验结果:输入:int data[] = {1, 2, 3, 4, -1, -1, 5, 6, -1, -1, 7, 8};输出:前序遍历结果:1 2 4 5 3 6 7 8中序遍历结果:4 2 5 1 6 3 7 8后序遍历结果:4 5 2 6 8 7 3 1层次遍历结果:1 2 3 4 5 6 7 8通过本次实验,我深入理解了二叉树的性质和遍历方式,并掌握了二叉树的基本操作。
数据结构二叉树的实验报告数据结构二叉树的实验报告一、引言数据结构是计算机科学中非常重要的一个领域,它研究如何组织和存储数据以便高效地访问和操作。
二叉树是数据结构中常见且重要的一种,它具有良好的灵活性和高效性,被广泛应用于各种领域。
本实验旨在通过实际操作和观察,深入了解二叉树的特性和应用。
二、实验目的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:这次实验大多用了递归的算法,比较好理解。
数据结构二叉树实验报告1. 引言二叉树是一种常见的数据结构,由节点(Node)和链接(Link)构成。
每个节点最多有两个子节点,分别称为左子节点和右子节点。
二叉树在计算机科学中被广泛应用,例如在搜索算法中,二叉树可以用来快速查找和插入数据。
本实验旨在通过编写二叉树的基本操作来深入理解二叉树的特性和实现方式。
2. 实验内容2.1 二叉树的定义二叉树可以用以下方式定义:class TreeNode:def__init__(self, val):self.val = valself.left =Noneself.right =None每个节点包含一个值和两个指针,分别指向左子节点和右子节点。
根据需求,可以为节点添加其他属性。
2.2 二叉树的基本操作本实验主要涉及以下二叉树的基本操作:•创建二叉树:根据给定的节点值构建二叉树。
•遍历二叉树:将二叉树的节点按照特定顺序访问。
•查找节点:在二叉树中查找特定值的节点。
•插入节点:向二叉树中插入新节点。
•删除节点:从二叉树中删除特定值的节点。
以上操作将在下面章节详细讨论。
3. 实验步骤3.1 创建二叉树二叉树可以通过递归的方式构建。
以创建一个简单的二叉树为例:def create_binary_tree():root = TreeNode(1)root.left = TreeNode(2)root.right = TreeNode(3)root.left.left = TreeNode(4)root.left.right = TreeNode(5)return root以上代码创建了一个二叉树,根节点的值为1,左子节点值为2,右子节点值为3,左子节点的左子节点值为4,左子节点的右子节点值为5。
3.2 遍历二叉树二叉树的遍历方式有多种,包括前序遍历、中序遍历和后序遍历。
以下是三种遍历方式的代码实现:•前序遍历:def preorder_traversal(root):if root:print(root.val)preorder_traversal(root.left)preorder_traversal(root.right)•中序遍历:def inorder_traversal(root):if root:inorder_traversal(root.left)print(root.val)inorder_traversal(root.right)•后序遍历:def postorder_traversal(root):if root:postorder_traversal(root.left)postorder_traversal(root.right)print(root.val)3.3 查找节点在二叉树中查找特定值的节点可以使用递归的方式实现。
数据结构二叉树综合实验报告数据结构二叉树综合实验报告1.引言在计算机科学中,二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。
二叉树具有广泛的应用场景,如在搜索算法、图形处理和编译器设计中等。
本报告旨在介绍我们进行的二叉树综合实验,包括实验目的、实验过程中的具体步骤和实验结果分析等。
2.实验目的本实验的主要目的是通过设计和实现二叉树的基本操作,加深对二叉树的理解,并掌握二叉树的基本算法和应用。
具体的实验目标包括:- 熟悉二叉树的基本概念和性质;- 掌握二叉树的创建、插入和删除操作;- 实现二叉树的遍历算法,包括前序、中序和后序遍历;- 实现二叉树的搜索功能;- 进行基于二叉树的排序实验。
3.实验步骤3.1 二叉树的创建首先,我们需要创建一个空的二叉树。
通过定义二叉树的节点结构和指针,可以动态地分配内存空间用于创建节点,并建立节点之间的连接关系。
3.2 节点的插入在已有的二叉树中,我们可以向其中插入新的节点。
插入操作通常涉及到比较节点的键值大小,然后根据比较结果决定插入新节点的位置。
3.3 节点的删除除了插入节点,我们也可能需要从二叉树中删除节点。
删除操作通常需要考虑节点的子节点情况,例如,被删除的节点是否有左子节点、右子节点或者同时存在。
3.4 二叉树的遍历二叉树的遍历操作可以按照不同的顺序进行,包括前序(根-左-右)、中序(左-根-右)和后序(左-右-根)遍历。
在实验中,我们需要实现这三种遍历算法,并观察它们的输出结果。
3.5 二叉树的搜索在已有的二叉树中,我们可根据节点的键值进行搜索操作。
通过比较键值,我们可以判断在左子树或右子树中进行进一步的搜索,直至找到目标节点或确定目标节点不存在于二叉树中。
3.6 基于二叉树的排序二叉树可以作为一种排序算法的基础结构。
在实验中,我们可以通过节点的插入操作构建一个包含数据集的二叉树,并通过中序遍历获取有序的数据。
数据结构二叉树实验报告总结一、实验目的本次实验的主要目的是通过对二叉树的学习和实践,掌握二叉树的基本概念、性质和遍历方式,加深对数据结构中树形结构的理解。
二、实验内容1. 二叉树的基本概念和性质在本次实验中,我们首先学习了二叉树的基本概念和性质。
其中,二叉树是由节点组成的有限集合,并且每个节点最多有两个子节点。
同时,我们还学习了二叉树的高度、深度、层数等概念。
2. 二叉树的遍历方式在了解了二叉树的基本概念和性质之后,我们开始学习如何遍历一个二叉树。
在本次实验中,我们主要学习了三种遍历方式:前序遍历、中序遍历和后序遍历。
其中,前序遍历指先访问节点自身再访问左右子节点;中序遍历指先访问左子节点再访问自身和右子节点;后序遍历指先访问左右子节点再访问自身。
3. 二叉搜索树除了以上内容之外,在本次实验中我们还学习了一种特殊的二叉树——二叉搜索树。
二叉搜索树是一种特殊的二叉树,它的每个节点都满足左子节点小于该节点,右子节点大于该节点的性质。
由于这个性质,二叉搜索树可以被用来进行快速查找、排序等操作。
三、实验过程1. 实现二叉树的遍历方式为了更好地理解和掌握二叉树的遍历方式,我们首先在编程环境中实现了前序遍历、中序遍历和后序遍历。
在代码编写过程中,我们需要考虑如何递归地访问每个节点,并且需要注意访问顺序。
2. 实现二叉搜索树为了更好地理解和掌握二叉搜索树的特性和操作,我们在编程环境中实现了一个简单的二叉搜索树。
在代码编写过程中,我们需要考虑如何插入新节点、删除指定节点以及查找目标节点等操作。
3. 实验结果分析通过对代码运行结果进行分析,我们可以清晰地看到每个遍历方式所得到的结果以及对应的顺序。
同时,在对二叉搜索树进行操作时,我们也可以看到不同操作所产生的不同结果。
四、实验总结通过本次实验,我们进一步加深了对二叉树的理解和掌握,学习了二叉树的遍历方式以及二叉搜索树的特性和操作。
同时,在编程实践中,我们也进一步熟悉了代码编写和调试的过程。
实验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.顺序存储七、思考讨论题或体会或对改进实验的建议通过这次实验,我掌握了二叉树的顺序存储和链式存储,体会了二叉树的存储结构的特性,掌握了二叉树的树上相关操作。
实验报告:二叉树题目:建立一棵二叉树,数据以字符串形式从键盘输入,在此二叉树上完成:(1)前序、中序、后序遍历(2)求出叶子数(3)求树高(4)左右子树交换,输出交换后的前序、中序遍历序列分析:建树:输入的字符串序列为带有空节点的前序遍历序列(空节点用*表示)。
①:前序,中序,后序遍历:递归遍历②:求叶子数:当一个节点的左右孩子都是NULL时,此节点即为叶子节点。
③:求树高当前节点的树高等于其左右孩子树高大的加1。
④:左右子树交换:对于每个节点,将其左右孩子交换,再递归对其左右子树交换。
测试结果:附:源码#include <iostream>#include <stdlib.h>using namespace std;struct Bintree{char data;Bintree* lchild;Bintree* rchild;};Bintree *head;int sp;/* 已知一棵二叉树的前序序列,建立这棵树*/ void CreateTree(Bintree *&p,char a[]){Bintree *temp;if(a[sp]!=0){if(a[sp]=='*'){p=NULL;sp++;return ;}p=new Bintree;p->data=a[sp++];CreateTree(p->lchild,a);CreateTree(p->rchild,a);}else p=NULL;}/* 求一棵树的高度*/int Depth(Bintree *&t){int lh , rh ;if( t == NULL ){return 0 ;}else{lh = Depth( t->lchild ) ;rh = Depth( t->rchild ) ;return ( lh > rh ? lh : rh ) + 1 ;}}/* 将二叉树的左右子树互换*/ void Exchange1(Bintree *&t){Bintree *temp;if(t){Exchange1(t->lchild);Exchange1(t->rchild);temp=t->lchild;t->lchild=t->rchild;t->rchild=temp;}}/* 按照前序递归遍历二叉树*/ void Preorder1(Bintree *&t){if(t!=NULL){printf("%c",t->data);Preorder1(t->lchild);Preorder1(t->rchild);}}/* 按照中序递归遍历二叉树*/ void Inorder1(Bintree *&t){if(t!=NULL){Inorder1(t->lchild);printf("%c",t->data);Inorder1(t->rchild);}}/* 按照后序递归遍历二叉树*/void Posorder1(Bintree *&t){if(t!=NULL){Posorder1(t->lchild);Posorder1(t->rchild);printf("%c",t->data);}}/* 递归法求叶子结点个数*/int Leaves_Num1(Bintree *&t){if(t){if(t->lchild==NULL&&t->rchild==NULL){return 1;}return Leaves_Num1(t->lchild)+Leaves_Num1(t->rchild);}return 0;}/*******************************************/int main (){char a[100];memset(a,0,sizeof(a));cout<<"输入带有空节点的前序遍历序列(空节点用*表示)"<<endl;cin>>a;sp=0;CreateTree(head,a);cout<<"前序遍历:"<<endl;Preorder1(head);cout<<endl;cout<<"中序遍历:"<<endl;Inorder1(head);cout<<endl;cout<<"后序遍历:"<<endl;Posorder1(head);cout<<endl;cout<<"叶子数:"<<Leaves_Num1(head)<<endl;cout<<"树高:"<<Depth(head)<<endl;cout<<"左右子树交换后"<<endl;Exchange1(head);cout<<"前序遍历:"<<endl;Preorder1(head);cout<<endl;cout<<"中序遍历:"<<endl;Inorder1(head);cout<<endl;cout<<"后序遍历:"<<endl;Posorder1(head);cout<<endl;return 0;}。
数据结构二叉树遍历实验报告正文:1.实验目的本实验旨在实现二叉树的四种遍历方式:前序遍历、中序遍历、后序遍历和层次遍历,并对其进行验证和性能评估。
2.实验原理2.1 二叉树的定义二叉树是一种特殊的树状结构,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。
2.2 二叉树的遍历方式2.2.1 前序遍历前序遍历的顺序是先访问根节点,然后递归地遍历左子树和右子树。
2.2.2 中序遍历中序遍历的顺序是先递归地遍历左子树,然后访问根节点,最后递归地遍历右子树。
2.2.3 后序遍历后序遍历的顺序是先递归地遍历左子树和右子树,最后访问根节点。
2.2.4 层次遍历层次遍历按照二叉树的层次从上到下、从左到右的顺序遍历节点。
3.实验内容3.1 实现二叉树的数据结构首先,我们需要定义二叉树的数据结构。
二叉树节点应包含键值和左右子节点的指针。
3.2 实现二叉树的各种遍历方式接下来,我们实现四种遍历方式:前序遍历、中序遍历、后序遍历和层次遍历。
针对每种遍历方式,编写相应的算法实现逻辑。
3.3 实验验证和性能评估使用已实现的算法,对一棵二叉树进行各种遍历方式操作,并将结果输出。
验证输出结果与预期结果是否一致。
同时,记录每种遍历方式的算法时间复杂度和空间复杂度,并进行性能评估。
4.实验结果与分析对于给定的二叉树,分别进行了前序遍历、中序遍历、后序遍历和层次遍历操作,并得到了相应的输出结果。
结果与预期相符。
通过对算法的时间复杂度和空间复杂度的计算和分析,可以看出各种遍历方式的效率和资源消耗情况。
5.结论本实验成功实现了二叉树的四种遍历方式,并验证了其正确性。
同时,对这些遍历方式的性能进行了评估,为后续使用二叉树进行数据操作提供了参考。
附件:无法律名词及注释:- N/A。
数据结构实验报告二叉树二叉树是一种重要的数据结构,广泛应用于计算机科学和算法设计中。
在本次实验中,我们通过实际编程实践,深入理解了二叉树的基本概念、性质和操作。
一、二叉树的定义和基本性质二叉树是一种特殊的树结构,每个节点最多有两个子节点。
它具有以下基本性质:1. 根节点:二叉树的顶部节点称为根节点,它没有父节点。
2. 子节点:每个节点最多有两个子节点,分别称为左子节点和右子节点。
3. 叶节点:没有子节点的节点称为叶节点。
4. 深度:从根节点到某个节点的路径长度称为该节点的深度。
5. 高度:从某个节点到其叶节点的最长路径长度称为该节点的高度。
6. 层次遍历:按照从上到下、从左到右的顺序遍历二叉树的节点。
二、二叉树的实现在本次实验中,我们使用C++语言实现了二叉树的基本操作,包括创建二叉树、插入节点、删除节点、查找节点等。
通过这些操作,我们可以方便地对二叉树进行增删改查。
三、二叉树的遍历二叉树的遍历是指按照某种顺序访问二叉树的所有节点。
常用的遍历方式有三种:前序遍历、中序遍历和后序遍历。
1. 前序遍历:先访问根节点,然后依次递归遍历左子树和右子树。
2. 中序遍历:先递归遍历左子树,然后访问根节点,最后递归遍历右子树。
3. 后序遍历:先递归遍历左子树,然后递归遍历右子树,最后访问根节点。
四、二叉树的应用二叉树在计算机科学和算法设计中有广泛的应用。
以下是一些常见的应用场景:1. 二叉搜索树:二叉搜索树是一种特殊的二叉树,它的左子树的值都小于根节点的值,右子树的值都大于根节点的值。
它可以高效地支持插入、删除和查找操作,常用于有序数据的存储和检索。
2. 堆:堆是一种特殊的二叉树,它的每个节点的值都大于(或小于)其子节点的值。
堆常用于实现优先队列等数据结构。
3. 表达式树:表达式树是一种用二叉树表示数学表达式的方法。
通过对表达式树的遍历,可以实现对数学表达式的计算。
4. 平衡树:平衡树是一种特殊的二叉树,它的左右子树的高度差不超过1。
数据结构二叉树遍历实验报告数据结构二叉树遍历实验报告1. 实验目的本实验旨在通过实现二叉树的前序、中序和后序遍历算法,加深对二叉树遍历的理解,并验证算法的正确性。
2. 实验原理2.1 二叉树二叉树是一种特殊的树状数据结构,它的每个节点最多只能有两个子节点。
二叉树可以为空树,也可以是由根节点、左子树和右子树组成的非空树。
2.2 遍历算法二叉树的遍历算法包括前序遍历、中序遍历和后序遍历。
- 前序遍历:先访问根节点,然后依次递归访问左子树和右子树。
- 中序遍历:先递归访问左子树,然后访问根节点,最后递归访问右子树。
- 后序遍历:先递归访问左子树,然后递归访问右子树,最后访问根节点。
3. 实验过程3.1 数据结构设计首先,我们需要设计表示二叉树的数据结构。
在本次实验中,二叉树的每个节点包含三个成员变量:值、左子节点和右子节点。
我们可以使用面向对象编程语言提供的类来实现。
具体实现如下:```pythonclass TreeNode:def __init__(self, val=0, left=None, right=None): self.val = valself.left = leftself.right = right```3.2 前序遍历算法前序遍历算法的实现主要包括以下步骤:1. 若二叉树为空,则返回空列表。
2. 创建一个栈,用于存储遍历过程中的节点。
3. 将根节点入栈。
4. 循环执行以下步骤,直到栈为空:- 弹出栈顶节点,并将其值添加到结果列表中。
- 若当前节点存在右子节点,则将右子节点压入栈。
- 若当前节点存在左子节点,则将左子节点压入栈。
具体实现如下:```pythondef preorderTraversal(root):if not root:return []stack = []result = []stack.append(root)while stack:node = stack.pop()result.append(node.val)if node.right:stack.append(node.right)if node.left:stack.append(node.left)return result```3.3 中序遍历算法中序遍历算法的实现主要包括以下步骤:1. 若二叉树为空,则返回空列表。
数据结构实验报告—二叉树目录1. 引言1.1 背景1.2 目的2. 前期准备2.1 问题定义2.2 数据准备3. 算法设计3.1 插入节点3.2 删除节点3.3 查找节点3.4 遍历二叉树4. 实验过程4.1 实验环境4.2 实验步骤5. 实验结果与分析5.1 插入节点的结果 5.2 删除节点的结果 5.3 查找节点的结果5.4 遍历二叉树的结果6. 总结与讨论6.1 实验总结6.2 实验改进方向7. 结论8. 参考文献1. 引言1.1 背景介绍二叉树的概念和应用领域,以及在数据结构中的重要性。
1.2 目的明确本实验的目标,即设计一个能够实现插入、删除、查找和遍历二叉树的算法,并对其进行实验验证。
2. 前期准备2.1 问题定义对二叉树的基本操作进行定义,包括插入节点、删除节点、查找节点和遍历二叉树。
2.2 数据准备准备一组用于测试的数据集,包括插入节点、删除节点和查找节点时所需的数据。
3. 算法设计3.1 插入节点详细描述如何设计实现插入节点的算法,并分析算法的时间复杂度和空间复杂度。
3.2 删除节点详细描述如何设计实现删除节点的算法,并分析算法的时间复杂度和空间复杂度。
3.3 查找节点详细描述如何设计实现查找节点的算法,并分析算法的时间复杂度和空间复杂度。
3.4 遍历二叉树详细描述如何设计实现遍历二叉树的算法,并分析算法的时间复杂度和空间复杂度。
4. 实验过程4.1 实验环境描述实验所用的编程语言和相关工具的环境配置。
4.2 实验步骤详细描述实验的具体步骤,包括数据准备、算法实现、代码编写、实验运行和结果分析等。
5. 实验结果与分析5.1 插入节点的结果展示插入节点的实验结果,并对结果进行详细分析和讨论。
5.2 删除节点的结果展示删除节点的实验结果,并对结果进行详细分析和讨论。
5.3 查找节点的结果展示查找节点的实验结果,并对结果进行详细分析和讨论。
5.4 遍历二叉树的结果展示遍历二叉树的实验结果,并对结果进行详细分析和讨论。
课程实验报告课程名称:数据结构实验专业班级:学号:姓名:指导教师:报告日期:计算机科学与技术学院5 基于二叉存储结构实二叉树的基本操作 (3)1.1 问题描述 (3)1.2二叉树的操作系统设计 (3)1.2.1 系统总体设计 (3)1.2.2 有关常量和类型定义 (4)1.2.3 算法设计&算法分析 (5)1.3二叉树系统实现与测试 (9)1.3.1 系统实现 (9)1.3.2 系统测试 (47)1.4 实验小结 (55)5 基于二叉存储结构实二叉树的基本操作1.1 问题描述数据结构描述:在计算机科学中,二叉树是每个节点最多有两个子树的树结构。
通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。
二叉树常被用于实现二叉查找树和二叉堆,是一种非常重要的数据结构。
其结构如图:树根左孩子右孩子图-3.1 二叉树结构示意图本次试验要完成的顺序表和链式栈的相关操作。
算法有:1.构造二叉树数组2.创建二叉树3.清空二叉树4.判断二叉树是否为空5.返回指定元素的数据6.在指定位置插入和删除子树7.给指定元素结点赋值8.前序遍历二叉树9.中序遍历二叉树遍历10.后序便利二叉树11.层序遍历二叉树12.返回指定结点的左兄弟、右兄弟、双亲、左孩子和右孩子13.计算二叉树深度。
1.2二叉树的操作系统设计1.2.1 系统总体设计本系统包括22个模块的功能,包括栈的创建,销毁,清空,判断,计算长度,对指定元素操作,访问二叉树中元素等。
系统总体结构如图:图-3.2 函数调用关系1.2.2 有关常量和类型定义#define OK 1#define ERROR 0#define FALSE 0#define TRUE 1#define INIT_TREELINK_LENTH 20 #define INCREASE_LENTH 10#define INIT_STACK_LENTH 10初始化树根数组创建二叉树清空二叉树取根地址指定左孩子地址指定右孩子地址指定双亲地址主函数指定左兄弟地址指定右兄弟地址指定插入子树指定删除子树指定元素赋值指定元素取值typedef char Elemtype;typedef struct BiTreeNode //树结点定义{struct BiTreeNode *lChild;Elemtype data;int Node_Num;struct BiTreeNode *rChild;int flag;}BiTreeNode;typedef struct TreeLink //根数组{BiTreeNode *root;}TreeLink;typedef struct //定义顺序栈结构{BiTreeNode* stack[INIT_STACK_LENTH];int stack_top;}SqStack;typedef struct Qnode //定义队列结构{BiTreeNode* data;struct Qnode *next;}Qnode;typedef struct LinkQueue{Qnode *front;Qnode *rear;}LinkQueue;1.2.3 算法设计&算法分析1.构造树根数组创建一个树根数组,长度为INIT_ETRRLINK_LENTH,每一个元素的值为NULL 输入:数组首元素的地址输出:一个树根数组时间复杂度为常量阶,O(1);空间复杂度为常量阶,O(20)2.清空二叉树直接将root置为NULL输入:树根的地址输出:销毁成功OK或失败False时间复杂度:常量阶,O(1);空间复杂度:常量阶O(0)3.判空二叉树判断root是否指向,是的即为空,否则不为空输入:树根的地址输出:是否为空OK或者FALSE时间复杂度:常量阶O(1);空间复杂度:O(0)4.创建二叉树递归创建结点,没有孩子则输入#;返回树的指针并赋值个树根指针并赋给对应的树根指针;输入:无输出:一个二叉树的树根地址时间复杂度:线性阶O(n);空间复杂度:指数阶O(n2);6.计算二叉树深度输入:树根的地址输出:树的深度如果为空二叉树,则返回FALSE否则,对左右子树递归调用自身函数,最后比较左右子树的深度,取大加一时间复杂度:常量阶,O(n);空间复杂度:指数阶,O(n2)7.前序遍历二叉树用递归和非递归两种方式进行遍历;输入:树根地址输出:打印遍历结果如果为空,返回FALSE时间复杂度:线性阶,O(n);空间复杂度:线性阶,O(n)8.中遍历二叉树用递归和非递归两种方式进行遍历;输入:树根地址输出:打印遍历结果如果为空,返回FALSE时间复杂度:线性阶,O(n);空间复杂度:线性阶,O(n)9.后序遍历二叉树用递归和非递归两种方式进行遍历;输入:树根地址输出:打印遍历结果如果为空,返回FALSE时间复杂度:线性阶,O(n);空间复杂度:线性阶,O(n)10.层序遍历二叉树用一个队列保存结点地址,层序遍历输入:树根地址输出:屏幕打印遍历结果如果为空返回FALSE;时间复杂度:线性阶,O(n);空间复杂度:线性阶,O(n);11.返回根地址输入:树根地址数度:树根地址如果为空则返回FALSE;时间复杂度:常数阶,O(0);空间复杂度:常熟阶,O(0);12.返回指定结点左右孩子地址输入:树根地址,结点编号输出:对应结点的左(右)孩子地址如果为空则返回FALSE,如果没有左(右)孩子则返回NULL,如果没有输入的元素则打印提示;时间复杂度:线性阶,O(N),空间复杂度:线性阶O(n);13.返回指定结点左右兄弟地址输入:树根地址,结点编号输出:对应结点的左(右)兄弟地址如果为空则返回FALSE,如果没有左(右)兄弟则返回NULL,如果没有输入的元素则打印提示;时间复杂度:线性阶,O(N),空间复杂度:线性阶O(n);14.返回指定结点双亲地址输入:树根地址,结点编号输出:对应结点的双亲地址如果为空则返回FALSE,如果没有双亲则返回NULL,如果没有输入的元素则打印提示;时间复杂度:线性阶,O(N),空间复杂度:线性阶O(n);15.对指定结点赋值(取值)输入:树根指针,要赋的值输出:对应元素的值如果为空则返回FALSE时间复杂度:线性阶,O(N),空间复杂度:线性阶O(n);16.在指定位置插入(删除)子树输入:树根指针,要插入的指针输出:插入(删除)后的树根地址如果为空返回FALSE时间复杂度:线性阶,O(N),空间复杂度:线性阶O(n);1.3二叉树系统实现与测试1.3.1 系统实现1.编程环境的设置本次实验用的visual stdio 2012,语言使用C语言。
2.函数调用关系主程序,调用各个功能函数,在与栈有关的功能函数中调用对栈的相关操作函数,在与队列有关的功能函数中调用对队列的相关操作函数。
3.程序清单int InitQueue(LinkQueue *Q);int QueueEmpty(LinkQueue *Q);BiTreeNode* DeQueue(LinkQueue *Q);int EnQueue(LinkQueue *Q,BiTreeNode *e);int InitStack(SqStack *L);int StackEmpty(SqStack *L);int Push(SqStack *L,BiTreeNode *e);BiTreeNode* Pop(SqStack *L);TreeLink* InitBiTree();BiTreeNode* CreatBiTree(void);int Visit(Elemtype p);void RecursionPreOrderTraverse(BiTreeNode *T);void UnRecursionPreOrderTraverse(BiTreeNode *T) ;int BiTreeEmpty(BiTreeNode *T);int BiTreeDepth(BiTreeNode *T);void RecursionInOrderTraverse(BiTreeNode *T) ;void UnRecursionInOrderTraverse(BiTreeNode *T);void RecursionPostOrderTraverse(BiTreeNode *T);void UnRecursionPostOrderTraverse(BiTreeNode *T);BiTreeNode* RightSibling(BiTreeNode *T,int i); BiTreeNode* LeftSibling(BiTreeNode *T,int i); BiTreeNode* Parent(BiTreeNode *T,int i); BiTreeNode* LeftChlid(BiTreeNode *T,int i); BiTreeNode* RightChlid(BiTreeNode *T,int i);int InsertChlid(BiTreeNode *T,int i,BiTreeNode *c); int DeleteChild(BiTreeNode *T,int i);int Assign(BiTreeNode *T,int i,Elemtype data); Elemtype Value(BiTreeNode *T,int i);源代码:#include<stdio.h>#include<stdlib.h>#define OK 1#define ERROR 0#define FALSE 0#define TRUE 1#define INIT_TREELINK_LENTH 20#define INCREASE_LENTH 10#define INIT_STACK_LENTH 10typedef char Elemtype;typedef struct BiTreeNode //树结点定义{struct BiTreeNode *lChild;Elemtype data;int Node_Num;struct BiTreeNode *rChild;int flag;}BiTreeNode;typedef struct TreeLink //根数组{BiTreeNode *root;}TreeLink;typedef struct //定义顺序栈结构{BiTreeNode* stack[INIT_STACK_LENTH];int stack_top;}SqStack;typedef struct Qnode //定义队列结构{BiTreeNode* data;struct Qnode *next;}Qnode;typedef struct LinkQueue{Qnode *front;Qnode *rear;}LinkQueue;int InitQueue(LinkQueue *Q);int QueueEmpty(LinkQueue *Q);BiTreeNode* DeQueue(LinkQueue *Q);int EnQueue(LinkQueue *Q,BiTreeNode *e);int InitStack(SqStack *L);int StackEmpty(SqStack *L);int Push(SqStack *L,BiTreeNode *e);BiTreeNode* Pop(SqStack *L);TreeLink* InitBiTree();BiTreeNode* CreatBiTree(void);int Visit(Elemtype p);void RecursionPreOrderTraverse(BiTreeNode *T); void UnRecursionPreOrderTraverse(BiTreeNode *T) ; int BiTreeEmpty(BiTreeNode *T);int BiTreeDepth(BiTreeNode *T);void RecursionInOrderTraverse(BiTreeNode *T) ; void UnRecursionInOrderTraverse(BiTreeNode *T); void RecursionPostOrderTraverse(BiTreeNode *T); void UnRecursionPostOrderTraverse(BiTreeNode *T); BiTreeNode* RightSibling(BiTreeNode *T,int i); BiTreeNode* LeftSibling(BiTreeNode *T,int i); BiTreeNode* Parent(BiTreeNode *T,int i);BiTreeNode* LeftChlid(BiTreeNode *T,int i);BiTreeNode* RightChlid(BiTreeNode *T,int i);int InsertChlid(BiTreeNode *T,int i,BiTreeNode *c);int DeleteChild(BiTreeNode *T,int i);int Assign(BiTreeNode *T,int i,Elemtype data);Elemtype Value(BiTreeNode *T,int i);/******************************************************************** *************函数名称:InitQueue(LinkQueue *Q)函数功能:初始化一个空的队列函数参数:队列基址********************************************************************* *************/int InitQueue(LinkQueue *Q){Q->rear=(Qnode*)malloc(sizeof(Qnode));Q->front=Q->rear;Q->front->next=NULL;Q->rear->data=NULL;return OK;}/******************************************************************** *************函数名称:EnQueue(LinkQueue *Q,Elemtype e)初始条件:队列已经存在函数功能:插入一个新的元素结点到队尾函数参数:队列基址和插入的数据********************************************************************* *************/int EnQueue(LinkQueue *Q,BiTreeNode *e){Qnode *p;p=(Qnode *)malloc(sizeof(Qnode));if(!p){printf("\n\t\t生成结点失败!");return ERROR;}p->data=e;p->next=Q->front;Q->rear->next=p;Q->rear=p;return OK;}/******************************************************************** *************函数名称:QueueEmpty(LinkQueue *Q)初始条件:队列已经存在函数功能:判断队列是否为空队列,是则返回TRUE,否则返回FALSE函数参数:队列基址********************************************************************* *************/int QueueEmpty(LinkQueue *Q){if(Q->front==Q->rear){return TRUE;}else{return FALSE;}}/******************************************************************** *************函数名称:DeQueue(LinkQueue *Q)初始条件:队列已经存在函数功能:删除队列首结点函数参数:队列基址**********************************************************************************/BiTreeNode* DeQueue(LinkQueue *Q){Qnode *p;BiTreeNode *e;if(QueueEmpty(Q)){printf("\n\t\t空队列,不能出队列!");return ERROR;}p=Q->front;Q->front=p->next;e=p->next->data;free(p);return e;}/******************************************************************** ***************************************************************函数名称:InitStack(SqStack *L)操作结果:构造一个空栈********************************************************************* **************************************************************/int InitStack(SqStack *L){L->stack_top=-1;return OK;}/******************************************************************** **************************************************************函数名称:StackEmpty(SqStack *L)初始条件:栈已存在操作结果:如果栈为空返回TRUE,不为空返回FALSE********************************************************************* *************************************************************/int StackEmpty(SqStack *L){if(L->stack_top<0)return TRUE;elsereturn FALSE;}/******************************************************************** **************************************************************函数名称:Push(SqStack *L,BiTreeNode e)初始条件:栈已存在操作结果:插入一个元素作为新的栈顶(新的栈顶元素入栈)********************************************************************* *************************************************************/int Push(SqStack *L,BiTreeNode *e){if(L->stack_top<INIT_STACK_LENTH){L->stack_top+=1;L->stack[L->stack_top]=e;}elseprintf("\n\t\t数据溢出\n");return OK;}/******************************************************************** **************************************************************函数名称:Pop(SqStack *L,BiTreeNode e)初始条件:栈已存在且不为空操作结果:用e保存当前栈顶元素(栈顶元素出栈)********************************************************************* *************************************************************/ BiTreeNode* Pop(SqStack *L){BiTreeNode *e;if(L->stack_top!=-1){e=L->stack[L->stack_top];L->stack_top-=1;}elseprintf("\n\t\t栈已经为空\n");return e;}/******************************************************************** **************************函数名称:InitBiTree()函数功能:生成数目为初始长度棵树的根节点,并用一个根数组存储函数参数:无函数返回:存储根结点的数组基址********************************************************************* *************************/TreeLink* InitBiTree(){TreeLink *T;T=(TreeLink*)malloc(sizeof(TreeLink)*INIT_TREELINK_LENTH);return T;}/******************************************************************** ***********************函数名称:CreatBiTree(BiTreeNode *T)函数功能:用递归的方式建立二叉树函数参数:树根的左子树指针********************************************************************* ***********************/BiTreeNode * CreatBiTree(void){Elemtype c;BiTreeNode *T;int i;T=NULL;printf("\n\t\t输入结点数据,没有则输入#:\n\t\tc=");scanf("%1s",&c);if(c!='#'){printf("\n\t\t输入结点编号\n\t\ti=");scanf("%d",&i);T=(BiTreeNode*)malloc(sizeof(BiTreeNode));T->data=c;T->Node_Num=i;printf("\n\t\t对左孩子:");T->lChild=CreatBiTree();printf("\n\t\t对右孩子:");T->rChild=CreatBiTree();}return T;}/******************************************************************** *********************函数名称:ClearBiTree(BiTreeNode *T)函数功能:将二叉树置为空函数参数:树根指针********************************************************************* *********************/int ClearBiTree(BiTreeNode *T){T=NULL;return OK;}/******************************************************************** ********************函数名称:BiTreeEmpty(BiTreeNode *T)函数功能:判断一棵树是否为空,是则返回TRUE,否则返回FALSE函数参数:树根指针********************************************************************* ********************/int BiTreeEmpty(BiTreeNode *T){if(T==NULL)return TRUE;elsereturn FALSE;}/******************************************************************** ********************函数名称:Visit(Elemtype p)函数功能:访问结点数据函数参数:数据域标识符********************************************************************* ********************/int Visit(Elemtype p){printf("%4c",p);return OK;}/******************************************************************** ********************函数名称:RecursionPreOrderTraverse(BiTreeNode *T)函数功能:使用递归的方法对二叉树进行前序遍历初始条件:二叉树已经存在且不为空函数参数:树根指针********************************************************************* ********************/void RecursionPreOrderTraverse(BiTreeNode *T){if(T){printf("%4c",T->data);RecursionPreOrderTraverse(T->lChild);RecursionPreOrderTraverse(T->rChild);}}/******************************************************************** ********************函数名称:UnRecursionPreOrder(BiTreeNode *T)函数功能:使用非递归的方法对二叉树进行前序遍历初始条件:二叉树已经存在且不为空函数参数:树根指针********************************************************************* ********************/void UnRecursionPreOrderTraverse(BiTreeNode *T){BiTreeNode *p=T;SqStack s;InitStack(&s);while(p||!StackEmpty(&s)){if(p){Visit(p->data);Push(&s,p);p=p->lChild;}else{p=Pop(&s);p=p->rChild;}}}/******************************************************************** ********************函数名称:RecursionIndOrderTraverse(BiTreeNode *T)函数功能:使用递归的方法对二叉树进行中序遍历初始条件:二叉树已经存在且不为空函数参数:树根指针********************************************************************* ********************/void RecursionInOrderTraverse(BiTreeNode *T){if(T){RecursionInOrderTraverse(T->lChild);Visit(T->data);RecursionInOrderTraverse(T->rChild);}}/******************************************************************** ********************函数名称:UnRecursionIndOrderTraverse(BiTreeNode *T)函数功能:使用非递归的方法对二叉树进行中序遍历初始条件:二叉树已经存在且不为空函数参数:树根指针********************************************************************* ********************/void UnRecursionInOrderTraverse(BiTreeNode *T){BiTreeNode *p=T;SqStack s;InitStack(&s);while(p||!StackEmpty(&s)){if(p){Push(&s,p);p=p->lChild;}else{p=Pop(&s);Visit(p->data);p=p->rChild;}}}/******************************************************************** ********************函数名称:RecursionIndOrderTraverse(BiTreeNode *T)函数功能:使用递归的方法对二叉树进行后序遍历初始条件:二叉树已经存在且不为空函数参数:树根指针********************************************************************* ********************/void RecursionPostOrderTraverse(BiTreeNode *T){if(T){RecursionPostOrderTraverse(T->lChild);RecursionPostOrderTraverse(T->rChild);Visit(T->data);}}/******************************************************************** ********************函数名称:UnRecursionPostdOrderTraverse(BiTreeNode *T)函数功能:使用非递归的方法对二叉树进行后序遍历初始条件:二叉树已经存在且不为空函数参数:树根指针********************************************************************* ********************/void UnRecursionPostOrderTraverse(BiTreeNode *T){}/******************************************************************** ********************函数名称:LevelOrderTraverse(BiTreeNode *T)函数功能:对二叉树进行层序遍历初始条件:二叉树已经存在且不为空函数参数:树根指针********************************************************************* ********************/int LevelOrderTraverse(BiTreeNode *T){BiTreeNode *p;LinkQueue Q;InitQueue(&Q);EnQueue(&Q,T);while(!QueueEmpty(&Q)){p=DeQueue(&Q);Visit(p->data);if(p->lChild!=NULL)EnQueue(&Q,p->lChild);if(p->rChild!=NULL)EnQueue(&Q,p->rChild);}return OK;}/******************************************************************** ********************函数名称:Destory(BiTreeNode *T)函数功能:将二叉树所占的空间释放掉初始条件:二叉树已经存在函数参数:树根指针********************************************************************* ********************/int DestoryBiTree(BiTreeNode *T){BiTreeNode *p=T,*q=NULL;SqStack s;InitStack(&s);while(p||!StackEmpty(&s)){if(p){q=p;p=p->lChild;free(q);}else{p=Pop(&s);q=p;p=p->rChild;free(q);}}}/******************************************************************** ********************函数名称:Root(BiTreeNode *T)函数功能:返回二叉树的根初始条件:二叉树已经存在函数参数:树根指针********************************************************************* ********************/BiTreeNode* Root(BiTreeNode *T){if(BiTreeEmpty(T)){printf("\n\t\t二叉树为空,无根!");return NULL;}return (T->lChild);}/******************************************************************** ********************函数名称:SaveBiTree(BiTreeNode *T)函数功能:将二叉树写入磁盘初始条件:二叉树已经存在且不为空函数参数:树根指针********************************************************************* ********************/int SaveBiTree(BiTreeNode *T){FILE *out;BiTreeNode *p=T;SqStack s;if((out=fopen("f:\\BiTree.txt","wb"))==NULL){printf("\n\t\t文件打开失败!");return ERROR;}InitStack(&s);while(p||!StackEmpty(&s)){if(p){fwrite(p,sizeof(BiTreeNode),1,out);p=p->lChild;}else{p=Pop(&s);fwrite(p,sizeof(BiTreeNode),1,out);p=p->rChild;}}fclose(out);return OK;}/******************************************************************** ********************函数名称:BiTreeDepth(BiTreeNode *T)函数功能:返回树的深度初始条件:二叉树已经存在且不为空函数参数:树根指针********************************************************************* ********************/int BiTreeDepth(BiTreeNode *T){int depth,ldepth,rdepth;if(BiTreeEmpty(T)){return 0;}ldepth=BiTreeDepth(T->lChild);rdepth=BiTreeDepth(T->rChild);depth=ldepth>rdepth?ldepth:rdepth;depth+=1;return depth;}/******************************************************************** ********************函数名称:Value(BiTreeNode *T,int i)函数功能:返回e的值初始条件:二叉树已经存在且不为空函数参数:树根指针,某结点编号********************************************************************* ********************/Elemtype Value(BiTreeNode *T,int i){BiTreeNode *p=T;SqStack s;InitStack(&s);while(p||!StackEmpty(&s)){if(p){if(p->Node_Num==i)return p->data;else{Push(&s,p);p=p->lChild;}}else{p=Pop(&s);p=p->rChild;}}}/******************************************************************** ********************函数名称:Assign(BiTreeNode *T,int i,Elemtype value)函数功能:将e赋值为value初始条件:二叉树已经存在且不为空函数参数:树根指针,某结点编号,要被赋的值********************************************************************* ********************/int Assign(BiTreeNode *T,int i,Elemtype data){BiTreeNode *p=T;SqStack s;InitStack(&s);while(p||!StackEmpty(&s)){if(p){if(p->Node_Num==i){p->data=data;return OK;}else{Push(&s,p);p=p->lChild;}}else{p=Pop(&s);p=p->rChild;}}}/******************************************************************** ********************函数名称:DeleteChild(BiTreeNode *T,int i,int RL)函数功能:删除结点的孩子结点初始条件:二叉树已经存在且不为空函数参数:树根指针,要被删除孩子的节点的编号,删除标记符********************************************************************* ********************/int DeleteChild(BiTreeNode *T,int i){BiTreeNode *p,*q,*o,*r;SqStack s1,s2,s3;if(BiTreeEmpty(T)){printf("\n\t\t二叉树为空!");return ERROR;}p=T;InitStack(&s1);while(p||!StackEmpty(&s1)){if(p){if(p->Node_Num==i){if(p->lChild){q=p->lChild;InitStack(&s2);while(q||!StackEmpty(&s2)){if(q){Push(&s2,q);q=q->lChild;}else{q=Pop(&s2);printf("\n\t\t%c",q->data);o=q;q=q->rChild;free(o);}}}if(p->rChild){q=p->rChild;InitStack(&s3);while(q||!StackEmpty(&s3)){if(q){Push(&s3,q);q=q->lChild;}else{q=Pop(&s3);printf("\n\t\t%c",q->data);r=q;q=q->rChild;free(r);}}}else{printf("\n\t\t该结点没有孩子结点!\n");}p->lChild=NULL;p->rChild=NULL;return OK;}else{Push(&s1,p);p=p->lChild;}}else{p=Pop(&s1);p=p->rChild;}}return OK;}/******************************************************************** *******************************函数名称:InsertChlid(BiTreeNode *T,int i,int RL,BiTreeNode c)初始条件:二叉树T存在,n为某个结点的编号,LR为0或1,非空二叉树c与T不相交且右子树为空函数功能:根据LR为0或者1,插入c为T中编号为n的结点的左或右子树,编号为n的结点的原有左子树或右子树则为c的右子树初始条件:二叉树已经存在且不为空#函数参数:树根指针,要被插入右子树的节点指针,删除标记符********************************************************************* ******************************/int InsertChlid(BiTreeNode *T,int i,BiTreeNode *c){BiTreeNode *p,*q;SqStack s;if(BiTreeEmpty(T)){printf("\n\t\t二叉树为空!");return NULL;}p=T;InitStack(&s);while(p||!StackEmpty(&s)){if(p){if(p->Node_Num==i){if(!p->rChild)p->rChild=c;else if(!p->lChild)p->lChild=c;else{q=p->lChild;p->lChild=c;c->rChild=q;}}else{Push(&s,p);p=p->lChild;}return OK;}else{p=Pop(&s);p=p->rChild;}}return OK;}/******************************************************************** *******************************函数名称:Parent(BiTreeNode *T,int i)初始条件:二叉树T存在,e是T中某个结点的值函数功能:若e指向的是非根结点,则返回他的父母结点,则返回NULL。