数据结构-树的实现实验报告
- 格式:doc
- 大小:550.00 KB
- 文档页数:29
数据结构树的实验报告数据结构树的实验报告一、引言数据结构是计算机科学中的重要概念,它可以帮助我们组织和管理数据,提高程序的效率和性能。
而树作为一种常见的数据结构,具有广泛的应用。
本实验旨在通过实践操作,深入理解树的基本概念、特性和操作。
二、实验目的1. 掌握树的基本概念和特性;2. 熟悉树的基本操作,如插入、删除、查找等;3. 理解树的遍历算法,包括前序、中序和后序遍历;4. 实现树的基本功能,并验证其正确性和效率。
三、实验过程1. 构建树的数据结构首先,我们需要定义树的数据结构。
树由节点组成,每个节点可以有零个或多个子节点。
我们可以使用面向对象的思想,创建一个节点类和树类。
节点类包含节点值和子节点列表的属性,以及插入、删除子节点等操作的方法。
树类则包含根节点的属性和遍历方法等。
2. 插入和删除节点在树中插入和删除节点是常见的操作。
插入节点时,我们需要找到合适的位置,并将新节点作为子节点添加到相应的位置。
删除节点时,我们需要考虑节点的子节点和兄弟节点的关系,并进行相应的调整。
通过实现这两个操作,我们可以更好地理解树的结构和特性。
3. 查找节点树中的节点可以通过值进行查找。
我们可以使用递归或迭代的方式,在树中进行深度优先或广度优先的搜索。
在查找过程中,我们需要注意节点的存在性和唯一性,以及查找算法的效率。
4. 树的遍历树的遍历是指按照一定的顺序访问树中的所有节点。
常见的遍历方式有前序、中序和后序遍历。
前序遍历先访问根节点,然后递归地访问左子树和右子树;中序遍历先递归地访问左子树,然后访问根节点,最后访问右子树;后序遍历先递归地访问左子树和右子树,最后访问根节点。
通过实现这三种遍历算法,我们可以更好地理解树的结构和遍历过程。
五、实验结果与分析通过实验,我们成功地实现了树的基本功能,并验证了其正确性和效率。
我们可以通过插入和删除节点操作,构建出不同形态的树,并进行查找和遍历操作。
在插入和删除节点时,树的结构会发生相应的变化,但其基本特性仍然保持不变。
*******************实践教学*******************兰州理工大学算法与数据结构课程设计题目:二叉树操作专业班级:08级计算机科学与技术(5)班姓名:金文鑫学号:08240511指导教师:李睿成绩:_______________一、实验目的:理解二叉树特别是完全二叉树的性质,掌握二叉树的存储结构(二叉链表);熟练掌握二叉树的常用操作算法(初始化、插入结点、删除结点、遍历等);初步掌握二叉树的应用。
二、实验内容:要求采用二叉链表作为存储结构,完成二叉树的建立,前序、中序和后序遍历的操作,求所有叶子及结点总数的操作等。
具体要求如下:①给出基于二叉链表的二叉树类的定义;②给出二叉树初始化(构造函数)的实现;③给出二叉树三种遍历算法的递归实现;④二叉树先序遍历的非递归算法实现;⑤利用二叉树的遍历算法求二叉树的结点数、二叉树的叶结点数、二叉树的高度;⑥二叉树的撤销删除三、实验步骤:1、需求分析:本演示程序用JA V A编写,完成树的生成,任意位置的插入、删除,以及遍历二叉树中的结点,查找和修改树中元素的值。
①输入的形式和输入值的范围:插入元素时需要输入插入的位置和元素的值;删除元素时输入删除元素的位置;遍历时采用三种遍历方法中的一种遍历方法;修改操作时需要输入的元素的值;查找操作时,需要找到要查找元素的位置。
在所有输入中,元素的值都是整数。
②输出的形式:在所有四种操作中都显示操作是否正确以及操作后树中的内容。
其中删除操作后显示删除的元素的值,遍历二叉树中的元素,查找操作、修改操作后显示修改的值。
③程序所能达到的功能:完成树的生成(通过插入操作)、插入、删除、遍历、查找、修改操作。
④测试数据:A.树中已有以50,25,75,12,37,43,30,33,87,93,97为关键字的结点B.插入操作中依次输入10,20,30,40,50,60,70,80,90,100十个数C.删除操作中输入10删除值为10的元素D.查找操作中输入20,30,40,50返回这个元素在树中的位置2.概要设计:1)为了实现上述程序功能,需要定义树的抽象数据类型:public int iData;public double dData;public Node leftChild;public Node rightChild;private Node root;int value;private Node getSuccessor;基本操作:{Tree ()操作结果:构造一个空的二叉树insert ()初始条件:是否存在一个空二叉树操作结果:往二叉树中插入数值delete ()初始条件:存在一非空的二叉树操作条件:将二叉树中的元素删除displayTree ()初始条件:存在一非空的树操作条件:显示非空树中的所有元素的值getString ()初始条件:存在一非空的二叉树操作结果:返回整个字符串的数值getChar ()初始条件:存在一非空的二叉树操作结果:返回字符型的数值getInt ()初始条件:存在一非空的二叉树操作结果:返回整型的数值find ()初始条件:存在一非空二叉树操作结果:从二叉树中查找某一元素traverse ()初始条件:存在一非空的二叉树操作结果:对二叉树中的元素进行遍历preorder ()初始条件:存在一非空的二叉树操作结果:对二叉树中的元素进行先根遍历inOrder ()初始条件:存在一非空的二叉树操作结果:对二叉树中的元素进行中根遍历postOrder ()初始条件:存在一非空的二叉树操作结果:对二叉树中的元素进行后根遍历DisplayNode ()初始条件:存在一非空的二叉树操作结果:显示出二叉树中的整形数值和双精度浮点型数值public static void main操作结果:调用主函数2)本程序包含14个函数:3.详细设计实现概要设计中定义的所有的数据类型,对每个操作给出java算法。
数据结构实验三实验报告数据结构实验三实验报告一、实验目的本次实验的目的是通过实践掌握树的基本操作和应用。
具体来说,我们需要实现一个树的数据结构,并对其进行插入、删除、查找等操作,同时还需要实现树的遍历算法,包括先序、中序和后序遍历。
二、实验原理树是一种非线性的数据结构,由结点和边组成。
树的每个结点都可以有多个子结点,但是每个结点只有一个父结点,除了根结点外。
树的基本操作包括插入、删除和查找。
在本次实验中,我们采用二叉树作为实现树的数据结构。
二叉树是一种特殊的树,每个结点最多只有两个子结点。
根据二叉树的特点,我们可以使用递归的方式实现树的插入、删除和查找操作。
三、实验过程1. 实现树的数据结构首先,我们需要定义树的结点类,包括结点值、左子结点和右子结点。
然后,我们可以定义树的类,包括根结点和相应的操作方法,如插入、删除和查找。
2. 实现插入操作插入操作是将一个新的结点添加到树中的过程。
我们可以通过递归的方式实现插入操作。
具体来说,如果要插入的值小于当前结点的值,则将其插入到左子树中;如果要插入的值大于当前结点的值,则将其插入到右子树中。
如果当前结点为空,则将新的结点作为当前结点。
3. 实现删除操作删除操作是将指定的结点从树中移除的过程。
我们同样可以通过递归的方式实现删除操作。
具体来说,如果要删除的值小于当前结点的值,则在左子树中继续查找;如果要删除的值大于当前结点的值,则在右子树中继续查找。
如果要删除的值等于当前结点的值,则有三种情况:- 当前结点没有子结点:直接将当前结点置为空。
- 当前结点只有一个子结点:将当前结点的子结点替代当前结点。
- 当前结点有两个子结点:找到当前结点右子树中的最小值,将其替代当前结点,并在右子树中删除该最小值。
4. 实现查找操作查找操作是在树中寻找指定值的过程。
同样可以通过递归的方式实现查找操作。
具体来说,如果要查找的值小于当前结点的值,则在左子树中继续查找;如果要查找的值大于当前结点的值,则在右子树中继续查找。
数据结构实验报告树是一种非线性的数据结构,它由节点和边组成,节点之间存在层次关系。
树的应用十分广泛,特别是在存储和检索数据上。
在本次实验中,我对树的应用进行了研究和实践,并撰写了本篇实验报告。
本次实验中,我首先学习了树的基本概念和相关术语。
树由根节点、子节点、叶节点以及它们之间的连接边组成。
每个节点可以有多个子节点,但只能有一个父节点(除了根节点)。
叶节点是没有子节点的节点。
这种层次结构使得树可以用来表示具有层次关系的数据,例如家谱、目录结构等。
接下来,我学习了树的不同种类和它们的特点。
最常见的树结构包括二叉树、二叉树(BST)、平衡二叉树、AVL树等。
二叉树是一种每个节点最多有两个子节点的树结构。
二叉树是二叉树的一种特殊形式,其中左子树的所有节点值都小于根节点的值,右子树的所有节点值都大于根节点的值。
平衡二叉树是一种高度平衡的二叉树,它的左右子树的高度差不超过1、AVL树是一种自平衡的二叉树,它通过旋转和重新平衡来保持树的平衡性。
为了更好地理解树的应用,我选择了二叉树(BST)作为本次实验的主要研究对象。
BST是一种高效的数据结构,可以用来存储一组有序的数据,并且支持快速的查找、插入和删除操作。
我首先实现了BST的基本操作,包括插入节点、删除节点和查找节点。
通过这些操作,我可以在BST中存储和检索数据。
在插入节点时,我按照BST的特性将节点插入到相应的位置,并保持树的有序性。
在删除节点时,我考虑了不同的情况,包括删除叶节点、删除只有一个子节点的节点以及删除有两个子节点的节点。
在查找节点时,我使用了递归的方式在树中查找节点的值。
接着,我实现了一些BST的扩展操作。
首先是中序遍历,它可以按照节点的值的升序输出BST中的所有节点。
其次是最小值和最大值的查找,它们分别返回BST中的最小值和最大值。
最后是查找一些节点的前驱和后继,前驱是小于该节点的最大节点,后继是大于该节点的最小节点。
这些扩展操作可以进一步提升BST的功能和灵活性。
2008级数据结构实验报告实验名称:实验三树学生姓名:班级:班内序号:学号:日期:2009年11月23日1.实验要求a. 实验目的通过选择两个题目之一进行实现,掌握如下内容:掌握二叉树基本操作的实现方法了解赫夫曼树的思想和相关概念学习使用二叉树解决实际问题的能力b. 实验内容利用二叉树结构实现赫夫曼编/解码器。
基本要求:1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立赫夫曼树2、建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每个字符的编码输出。
3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。
4、译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译码,并输出译码结果。
5、打印(Print):以直观的方式打印赫夫曼树(选作)6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。
2. 程序分析2.1 存储结构存储结构:二叉树示意图如下:2.2 关键算法分析核心算法思想:1.哈夫曼编码(Huffman Coding)是可变字长编码。
编码时借助哈夫曼树,也即带权路径长度最小的二叉树,来建立编码。
2.哈夫曼编码可以实现无损数据压缩。
单个字符用一个特定长度的位序列替代:在字符串中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。
关键算法思想描述和实现:关键算法1:统计字符出现的频度,记录出现的字符及其权值,对未出现的字符不予统计编码。
将统计的叶子节点编制成数组。
为创建哈夫曼树作准备。
C++实现:for(int i=0;str[i]!='\0';i++) //统计频度frequency[(short)str[i]]++;此处以一个一维的下标表示ascII编码,以元素之表示字符频度,解决统计字符的问题。
for(int j=0;j<128;j++) //统计叶子节点个数if(frequency[j]!=0) leaf++;此处扫描一遍上面建立的数组得到叶子节点的个数,则由(leaf*2-1)得到总的节点个数。
实验名称:树的操作实验实验目的:1. 理解树的基本概念和操作。
2. 掌握树的创建、插入、删除、查找等基本操作。
3. 熟悉树在计算机科学中的应用。
实验环境:1. 操作系统:Windows 102. 编程语言:Java3. 开发工具:Eclipse实验内容:1. 树的基本概念2. 树的创建3. 树的插入4. 树的删除5. 树的查找6. 树的应用实验步骤:一、树的基本概念1. 树的定义:树是一种非线性数据结构,由若干节点组成,每个节点有一个唯一的父节点(根节点除外),除了根节点外,其他节点都有一个子节点。
2. 树的术语:- 节点:树中的数据元素。
- 父节点:节点的直接前驱节点。
- 子节点:节点的直接后继节点。
- 根节点:没有父节点的节点。
- 叶节点:没有子节点的节点。
- 节点的度:节点拥有的子节点个数。
- 树的深度:根节点到叶节点的最长路径长度。
二、树的创建1. 创建二叉树:```javapublic class BinaryTree {private TreeNode root;public BinaryTree() {root = null;}public void createTree(int[] data) {if (data == null || data.length == 0) {return;}root = new TreeNode(data[0]);int i = 1;Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root);while (!queue.isEmpty()) {TreeNode node = queue.poll();if (i < data.length && data[i] != 0) {node.left = new TreeNode(data[i]); queue.offer(node.left);i++;}if (i < data.length && data[i] != 0) { node.right = new TreeNode(data[i]); queue.offer(node.right);i++;}}}}```2. 创建二叉搜索树:```javapublic class BinarySearchTree {private TreeNode root;public BinarySearchTree() {root = null;}public void createTree(int[] data) {if (data == null || data.length == 0) {return;}for (int i = 0; i < data.length; i++) {root = insert(root, data[i]);}}private TreeNode insert(TreeNode node, int data) { if (node == null) {return new TreeNode(data);}if (data < node.data) {node.left = insert(node.left, data);} else if (data > node.data) {node.right = insert(node.right, data);}return node;}}```三、树的插入1. 在二叉树中插入节点:```javapublic void insert(TreeNode node, int data) {if (node == null) {return;}if (data < node.data) {insert(node.left, data);} else if (data > node.data) {insert(node.right, data);}}```2. 在二叉搜索树中插入节点:```javaprivate TreeNode insert(TreeNode node, int data) { if (node == null) {return new TreeNode(data);}if (data < node.data) {node.left = insert(node.left, data);} else if (data > node.data) {node.right = insert(node.right, data);}return node;}```四、树的删除1. 在二叉树中删除节点:```javapublic void delete(TreeNode node, int data) {if (node == null) {return;}if (data < node.data) {delete(node.left, data);} else if (data > node.data) {delete(node.right, data);} else {if (node.left == null && node.right == null) { node = null;} else if (node.left == null) {node = node.right;} else if (node.right == null) {node = node.left;} else {TreeNode minNode = findMin(node.right);node.data = minNode.data;delete(node.right, minNode.data);}}}```2. 在二叉搜索树中删除节点:```javaprivate TreeNode delete(TreeNode node, int data) {if (node == null) {return null;}if (data < node.data) {node.left = delete(node.left, data);} else if (data > node.data) {node.right = delete(node.right, data);} else {if (node.left == null && node.right == null) { node = null;} else if (node.left == null) {node = node.right;} else if (node.right == null) {node = node.left;} else {TreeNode minNode = findMin(node.right);node.data = minNode.data;node.right = delete(node.right, minNode.data); }}return node;}```五、树的查找1. 在二叉树中查找节点:```javapublic TreeNode search(TreeNode node, int data) {if (node == null) {return null;}if (data == node.data) {return node;} else if (data < node.data) {return search(node.left, data);} else {return search(node.right, data);}}```2. 在二叉搜索树中查找节点:```javapublic TreeNode search(TreeNode node, int data) {if (node == null) {return null;}if (data == node.data) {return node;} else if (data < node.data) {return search(node.left, data);} else {return search(node.right, data);}}```六、树的应用1. 堆排序:利用二叉堆的属性,实现高效排序。
数据结构实验报告目的要求1.掌握二叉树的存储实现。
2.掌握二叉树的遍历思想。
3.掌握二叉树的常见算法的程序实现。
实验内容1.输入字符序列,建立二叉链表。
2.中序遍历二叉树:递归算法。
3.中序遍历二叉树:非递归算法。
(最好也能实现先序,后序非递归算法)4.求二叉树的高度。
5.求二叉树的叶子个数。
6.借助队列实现二叉树的层次遍历。
7.在主函数中设计一个简单的菜单,分别调试上述算法。
源程序:1.头文件:栈和队列stack#include <stdio.h>#include <stdlib.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2typedef char TElemType;typedef struct BiTNode{ TElemType data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;typedef BiTree SElemType;typedef BiTree QElemType;typedef BiTree Status;typedef struct Node{ //链栈的定义SElemType data;struct Node *next;}NODE;typedef struct{NODE *top;//链式栈的栈顶指针}Stack;//链式栈的操作示例void InitStack(Stack &S){S.top=(NODE *)malloc(sizeof(NODE));if (!S.top)exit(OVERFLOW);// 分配失败S.top->next=NULL;}int StackEmpty(Stack S){if (S.top->next==NULL) return(TRUE);else return(FALSE);}void Push(Stack &S,SElemType e){NODE *p;p=(NODE *)malloc(sizeof(NODE));if (!p)exit(OVERFLOW); // 分配失败p->data=e;p->next=S.top->next;S.top->next=p;}void Pop(Stack &S,SElemType &e){NODE *p;if (StackEmpty(S)) return;//栈空else {p=S.top->next;e=p->data;S.top->next=p->next;free(p);}}//队的操作typedef struct QNode{QElemType data;struct QNode *next;}QNode,*QueuePtr;typedef struct {QueuePtr front;QueuePtr rear;}LinkQueue;void InitQueue(LinkQueue &Q){ //初始化队列Q.front =Q.rear =(QueuePtr)malloc(sizeof(QNode));if(!Q.front) exit(OVERFLOW); //存储分配失败Q.front ->next =NULL;}int EnQueue(LinkQueue &Q,QElemType e) //插入元素e为Q的新的队尾元素{QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p) exit(OVERFLOW);p->data=e;p->next=NULL;Q.rear->next=p;Q.rear =p;return OK;}int DeQueue(LinkQueue &Q,QElemType &e) //删除Q的队头元素,用e返回其值{if(Q.front ==Q.rear ) return ERROR;QueuePtr p;p=Q.front ->next;e=p->data;Q.front->next=p->next ;if(Q.rear==p) Q.rear =Q.front ;free(p);return OK;}2.主程序#include <stdio.h>#include <stdlib.h>#include "math.h"#include "stack.h"int h=0,max=0,flag=0; //全局变量void CreateBiTree(BiTree &T){TElemType ch;scanf("%c",&ch);if (ch==' ') T=NULL;else{T=(BiTree)malloc(sizeof(BiTNode));T->data=ch;CreateBiTree(T->lchild);CreateBiTree(T->rchild);}}//2.中序遍历二叉树:递归算法。
数据结构实验报告本次数据结构实验的主要内容是关于树的相关操作,包括树的创建、遍历、查找等。
通过实验,我们将对树的基本概念和操作进行深入了解,并掌握相关算法的实现和应用。
首先,我们将介绍树的创建和基本操作。
树是一种非线性数据结构,由节点和边组成,具有层次关系。
在实验中,我们通过数组和链表两种方式来创建树。
数组表示法是将树的节点按照从上到下、从左到右的顺序存储在一维数组中,通过计算节点的下标来实现对树的操作。
链表表示法则是利用指针来表示节点之间的关系,实现树的各种操作。
在创建树的过程中,我们需要考虑节点的插入、删除和修改等操作,以及树的遍历方式,包括前序遍历、中序遍历和后序遍历。
其次,我们将介绍树的查找操作。
在实际应用中,我们经常需要对树进行查找操作,以找到特定的节点或者进行相关的数据处理。
在本次实验中,我们将学习如何实现对树的查找操作,包括深度优先搜索(DFS)和广度优先搜索(BFS)两种方式。
通过这些查找算法,我们可以高效地找到树中的特定节点,并进行相应的处理。
最后,我们将进行树的应用实例分析。
树作为一种重要的数据结构,在实际应用中有着广泛的应用。
我们将通过实例分析,介绍树在各种领域的应用,包括文件系统、数据库索引、网络路由等方面。
通过这些实例,我们可以更好地理解树的重要性和实际应用。
总之,本次数据结构实验涉及了树的创建、遍历、查找和应用等方面,通过实验,我们将对树的相关概念和操作有更深入的理解,并掌握相关算法的实现和应用。
希望通过本次实验,能够对数据结构有更深入的认识,为今后的学习和应用打下良好的基础。
数据结构设计性实验报告课程名称_____ ____ 题目名称学生学院专业班级学号学生姓名指导教师2010 年 7 月 6 日抽象数据类型:树的实现一.需求分析树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用,直观来看,树是以分支关系定义的内部结构。
树的结构在客观世界广泛存在,如人类社会的族谱和各种社会组织机构都可以用树来形象表示。
树在计算机领域中也得广泛应用,如在编译程序中,可用树来表示源程序的语法结构,又如在数据库系统中,树形结构也是信息的重要组织形式之一。
二.实验目的对某个具体的抽象数据类型,运用课程所学的知识和方法,设计合理的数据结构,并在此基础上实现该抽象数据类型的全部基本操作。
通过本设计性实验,检验所学知识和能力,发现学习中存在的问题。
进而达到熟练地运用本课程中的基础知识及技术的目的。
三.实验环境1、硬件:PC机2、软件:Microsoft V isual C++ 6.0四.设计说明本程序采用树的二叉链表(孩子指针-兄弟指针-双亲指针)存储表示,以下是树的结构定义和基本操作:ADT Tree{数据对象D:D是具有相同特性的数据元素的集合。
数据关系R:若D为空集,则称为空树;若D仅含有一个数据元素,则R为空集,否则R={H},H是如下二元关系:(1) 在D中存在唯一的称为根的数据元素root,它在关系H下无前驱;(2) 若D-{root}≠NULL,则存在D-{root}的一个划分D1,D2,D3, …,Dm(m>0),对于任意j ≠k(1≤j,k≤m)有Dj∩Dk=NULL,且对任意的i(1≤i≤m),唯一存在数据元素xi∈Di有<root,xi>∈H;(3) 对应于D-{root}的划分,H-{<root,xi>,…,<root,xm>}有唯一的一个划分H1,H2,…,Hm(m>0),对任意j≠k(1≤j,k≤m)有Hj∩Hk=NULL,且对任意i(1≤i≤m),Hi是Di 上的二元关系,(Di,{Hi})是一棵符合本定义的树,称为根root的子树。
基本操作P:InitTree(&T);操作结果:构造空树T。
DestroyTree(&T);初始条件:树T存在。
操作结果:销毁树T。
CreateTree(&T,definition);初始条件:definition给出树T的定义。
操作结果:按definition构造树T。
ClearTree(&T);初始条件:树T存在。
操作结果:将树T清为空树。
TreeEmpty(T);初始条件:树T存在。
操作结果:若T为空树,则返回TRUE,否则返回FALSE。
TreeDepth(T);初始条件:树T存在。
操作结果:返回T的深度。
Root(T);初始条件:树T存在。
操作结果:返回T的根。
V alue(T,cur_e);初始条件:树T存在,cur_e是T中某个结点。
操作结果:返回cur_e的值。
Assign(T,cur_e,value);初始条件:树T存在,cur_e是T中某个结点。
操作结果:结点cur_e赋值为value。
Parent(T,cur_e);初始条件:树T存在,cur_e是T中某个结点。
操作结果:若cur_e是T的非根结点,则返回它的双亲,否则函数值为“空”。
LeftChild(T,cur_e);初始条件:树T存在,cur_e是T中某个结点。
操作结果:若cur_e是T的非叶子结点,则返回它的最左孩子,否则返回“空”。
RightSibling(T,cur_e);初始条件:树T存在,cur_e是T中某个结点。
操作结果:若cur_e有右兄弟,则返回它的右兄弟,否则返回“空”。
InsertChild(&T,&p,I,c);初始条件:树T存在,p指向T中某个结点,1≤i≤p指结点的度+1,非空树c与T不相交。
操作结果:插入c为T中p指结点的第i棵子树。
DeleteChild(&T,&p,i);初始条件:树T存在,p指向T中某个结点,1≤i≤p指结点的度。
操作结果:删除T中p所指结点的第i棵子树。
TraverseTree(T,visit());初始条件:树T存在,visit是对结点操作的应用函数。
操作结果:按某种次序对T的每个结点调用函数visit()一次且至多一次。
一旦visit()失败,则操作失败。
CSTree Search(CSTree T,TElemType cur_e);初始条件:树T存在,cur_e可能是树T中某一个结点的值。
操作结果:在树T中查找值为cur_e的结点,找到返回指向这个结点的指针,否则返回空指针。
这个函数的作用是为了几个基本操作而服务的。
void LevelOrderTraverseTree(CSTree T,void (* visit)(TElemType));初始条件:树T存在,visit是对结点操作的应用函数。
操作结果:按层次次序对T的每一个结点调用函数visit()一次且至多一次。
void PreOrderTraverseTree(CSTree T,void(*visit)(TElemType));初始条件:树T存在,visit是对结点操作的应用函数。
操作函数:按先序次序(先根遍历)对T的每一个结点调用函数visit()一次且至多一次。
函数的功能实现是递归实现的。
void PostOrderTraverseTree(CSTree T,void (*visit)(TElemType));初始条件:树T存在,visit是对结点操作的应用函数。
操作结果:按后根遍历对T的每一个结点调用函数visit()一次且至多一次。
函数的功能实现是递归实现的。
void visit_print(CSTree p);初始条件:树T存在,visit_print是对结点操作的应用函数。
操作函数:对T的每一个结点调用函数visit_print()一次且至多一次。
与visit函数不一样的是,visit函数只是输出一个结点的值,而visit_print还输出其结点,第一个孩子,其右兄弟和双亲的值void Print(CSTree T,void (*visit)(CSTree));附加函数:用于显示树的所有内容。
初始条件:树T存在;操作结果:将树T的所有结点显示出来。
}ADT Tree五.数据处理树型数据存储样本:转化后树的二叉链表存储:RBEHDCFGAKRBCADEFGHK以下为数据样本测试:● 操作:判断树书否为空? 结果:不为空 ● 返回树T 的深度? 结果: 4● 返回树T 的根结点? 结果: A● 返回树F 结点的值? 结果: F● 将树根节点重新赋值为W ? 结果:A<—>W ● 求出结点A 的双亲? 结果: W● 求出结点A 的第一个孩子结点? 结果: D● 求出G 的第一个兄弟结点? 结果: H● 插入子树C 至A 中第2科子树?结果:XYZWBCADE FGHK XY Z● 删除树结点为R 的第三颗子树?结果:● 多种遍历方式遍历树前序遍历树: W-A-D-X-Y -Z-E-B 层次序遍历树: W-A-B-D-X-E-Y -Z 后序遍历树: D-Y -Z-X-E-A-B-W以下为运行EXE程序测试过程:XYZBADEW选择1:选择14:选择15:选择16:选择4:选择5:选择6:选择7:选择8:选择9:选择10:选择11:选择12:选择13:选择14:选择15:选择16:选择2:六.程序清单解读/**************************抽象数据类型树-源码*********************************/ #include<iostream>#include<conio.h>using namespace std;const int TRUE=1;const int FALSE=0;const int OK=1;const int ERROR=0;const int OVERFLOW=1;const int MAX=30;const char NIL=' ';/*****************树的二叉链表孩子-兄弟-双亲存储表示***************************/typedef struct CSnode{char data;CSnode *firstchild,*nextsibling,*parent;/*最左孩子指针、下一个兄弟指针、双亲指针*/}CSNode,*CSTree;/********************树的辅助队列结构定义和操作******************************/ typedef struct QNode{CSTree data;QNode *next;}QNode,*QueuePtr; /*队列的单链式存储结构*/typedef struct LinkQueue{QueuePtr front,rear; /*队头、队尾指针*/}LinkQueue;/*******************************队列定义**************************************/ /*构造一个空队列*/int InitQueue (LinkQueue &Q){if(!(Q.front=Q.rear=new QNode))exit(OVERFLOW);Q.front->next=NULL;return OK;}/*销毁队列Q*/int DestroyQueue(LinkQueue &Q){while(Q.front){Q.rear=Q.front->next;delete Q.front;Q.front=Q.rear;}return OK;}/*将Q清为空队列*/int ClearQueue (LinkQueue &Q){QueuePtr p,q;Q.rear=Q.front;p=Q.front->next;Q.front->next=NULL;while(p){q=p;p=p->next;delete q;}return OK;}/*若队列Q为空队列则返回TRUE,否则返回FALSE*/int QueueEmpty( LinkQueue Q){if(Q.front==Q.rear) return TRUE;else return FALSE;}/* 插入元素e为Q的新的队尾元素*/int EnQueue(LinkQueue &Q, CSTree e){QueuePtr p;if(!(p=new QNode)) exit(OVERFLOW);p->data=e;p->next=NULL;Q.rear->next=p;Q.rear=p;return OK;}/*若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR*/int DeQueue(LinkQueue &Q,CSTree &e){QueuePtr p;if(Q.front==Q.rear) return ERROR;p=Q.front->next;e=p->data;Q.front->next=p->next;if(Q.rear==p) Q.rear=Q.front;delete p;return OK;}/*****************************************************************************//***********************树的二叉链表孩子-兄弟-双亲存储定义*********************/ /*操作结果: 构造空树T*/int InitTree(CSTree &T){T=NULL;return OK;}/*初始条件: 树T存在*//*操作结果: 销毁树T*/void DestroyTree(CSTree &T){if(T){if(T->firstchild) DestroyTree(T->firstchild);if(T->nextsibling) DestroyTree(T->nextsibling);delete T;}}/*初始条件:树T存在*//*操作结果:按层次次序创建树T*/int CreateTree(CSTree &T){char c[MAX];CSTree p,p1,temp;LinkQueue q;InitQueue(q);cout<<"请输入根节点,空格代表跟为空:";fflush(stdin);c[0]=getche();if(c[0]!=NIL) /*非空树*/ {T=new CSNode;T->data=c[0];T->nextsibling=NULL;T->parent=NULL;EnQueue(q,T);while(!QueueEmpty(q)){DeQueue(q,p);cout<<"\n请输入"<<p->data<<"所有孩子的节点: ";gets(c);if(strlen(c)) /*树有孩子*/{p1=p->firstchild=new CSNode; /*建立长子节点*/temp=p; /*保存该根节点*/p1->parent=temp;/*建立双亲域*/p1->data=c[0];EnQueue(q,p1); /*第一个孩子节点入队列*/for(int i=1;i<strlen(c);++i){p1->nextsibling=new CSNode; /*建立下一个兄弟节点*/p1->nextsibling->data=c[i]; /* 下一个兄弟节点赋值*/p1->nextsibling->parent=temp; /*建立下一个兄弟节点双亲域*/EnQueue(q,p1->nextsibling); /*各兄弟入队*/p1=p1->nextsibling;}p1->nextsibling=NULL; /*最后的兄弟结点的nextsibling指针置为空*/}else /*树无孩子只有根节点*/{p->firstchild=NULL;}}}else T=NULL; /*空树*/ return OK;}/*初始条件:树T存在*//*操作结果:将树T清为空树*/void ClearTree(CSTree &T){if(T){if(T->firstchild) DestroyTree(T->firstchild);if(T->nextsibling) DestroyTree(T->nextsibling);delete T;T=NULL;}}/*初始条件:树T存在*//*操作结果:若T为空树,则返回TRUE,否则返回FALSE*/int TreeEmpty(CSTree T){if(T==NULL) return TRUE;else return FALSE;}/*初始条件:树T存在*//*操作条件:返回T的深度*/int TreeDepth(CSTree T){CSTree p;int depth,max=0;if(!T)return 0;if(!T->firstchild)return 1;for(p=T->firstchild;p;p=p->nextsibling){depth=TreeDepth(p); /*递归求深度*/if(depth>max) max=depth;}return max+1; /*返回深度要加上根节点*/ }/*初始条件: 树T存在*//*操作结果: 返回T的根*/char Root(CSTree T){if(T) return T->data;else{cout<<"\n树空,无根节点!";return NIL;}}/*初始条件:树T存在,cur_e可能是树T中某一个结点的值。