数据结构:树形结构完整代码,各种遍历方法,直接能跑
- 格式:doc
- 大小:45.00 KB
- 文档页数:11
前端处理树形结构数据的方法标题:前端处理树形结构数据的方法在前端开发中,我们常常会遇到需要处理树形结构数据的情况。
树形结构数据是一种非常常见的数据结构,例如文件目录、组织架构、菜单导航等都可以抽象为树形结构。
那么,在前端如何有效地处理这种数据呢?下面将介绍几种常用的方法。
一、递归方法递归是处理树形结构数据最直接的方法。
通过定义一个函数,该函数接受一个节点作为参数,然后遍历这个节点的所有子节点,对每个子节点调用自身,直到所有节点都被访问过。
这种方法的优点是逻辑清晰,易于理解,但是当数据量较大时,可能会导致栈溢出。
二、广度优先搜索(BFS)广度优先搜索是一种从根节点开始,逐层遍历的算法。
我们可以使用队列来实现BFS,首先将根节点入队,然后每次从队列中取出一个节点,将其子节点依次入队,直到队列为空。
这种方法的优点是可以保证每一层的节点都会按照顺序被访问到,而且不会导致栈溢出。
三、深度优先搜索(DFS)深度优先搜索是一种沿着某条路径尽可能深地搜索的算法。
我们可以使用栈来实现DFS,首先将根节点入栈,然后每次从栈顶取出一个节点,将其子节点依次入栈,直到栈为空。
这种方法的优点是可以保证一条路径上的所有节点都会按照顺序被访问到。
四、使用库除了自己实现上述算法外,我们还可以使用一些现成的库来处理树形结构数据,如lodash的_.tree方法,或是JavaScript标准库中的Array.from方法等。
这些库通常提供了丰富的API和优化过的算法,可以大大提高我们的开发效率。
总结:处理树形结构数据是前端开发中的常见任务,不同的方法有其适用的场景和优缺点。
在实际开发中,我们需要根据具体的需求和数据规模选择合适的方法。
同时,也可以利用现成的库来简化开发过程,提高代码质量。
JS树结构数据的遍历树结构是一种常见的数据结构,它由若干节点组成,节点之间存在一对多的关系。
在前端开发中,经常需要遍历树结构的数据来进行处理操作。
本文将介绍几种常用的树结构数据的遍历算法。
一、深度优先遍历(DFS)深度优先遍历是一种递归的遍历算法,其核心思想是先遍历子节点,再遍历父节点。
在JavaScript中,可以使用递归函数来实现深度优先遍历。
以下是一个简单的树结构数据的遍历例子:```javascriptfunction dfs(node)console.log(node.value);if (node.children)for (let child of node.children)dfs(child);}}```在上述例子中,dfs函数用来深度优先遍历树结构数据。
它首先打印当前节点的值,然后递归调用dfs函数遍历子节点。
二、广度优先遍历(BFS)广度优先遍历是一种按层次顺序遍历节点的算法,其核心思想是先遍历同一层的节点,再遍历下一层的节点。
在JavaScript中,可以使用队列来实现广度优先遍历。
以下是一个简单的树结构数据的遍历例子:```javascriptfunction bfs(root)let queue = [root];while (queue.length > 0)let node = queue.shift(;console.log(node.value);if (node.children)for (let child of node.children)queue.push(child);}}}```在上述例子中,bfs函数用来广度优先遍历树结构数据。
它使用一个队列来保存待遍历的节点,初始时将根节点加入队列,然后循环进行以下操作:从队列中取出一个节点,打印该节点的值,将该节点的子节点加入队列。
三、前序遍历、中序遍历和后序遍历(二叉树)在二叉树中,除了深度优先遍历和广度优先遍历外,还常用以下三种特殊的遍历方式:1. 前序遍历(pre-order):先访问根节点,再依次访问左子树和右子树。
树的遍历的三种方法树是一种非线性的数据结构,由节点和边组成的集合,节点代表实体,边代表节点之间的连接关系。
在树的操作中,遍历是一种重要的基本操作,它用于按照一定的顺序访问树中的所有节点。
树的遍历方法主要有三种:前序遍历、中序遍历和后序遍历。
下面将对这三种遍历方法进行详细的介绍。
一、前序遍历(Preorder Traversal)前序遍历是从根节点开始,按照根节点-左子树-右子树的顺序访问所有节点。
具体步骤如下:1.若树为空,则直接返回。
2.访问当前节点。
3.递归地前序遍历左子树。
4.递归地前序遍历右子树。
前序遍历的代码示例:```pythondef preorder(root):if root is None:returnprint(root.val)preorder(root.left)preorder(root.right)```二、中序遍历(Inorder Traversal)中序遍历是从左子树开始,按照左子树-根节点-右子树的顺序访问所有节点。
具体步骤如下:1.若树为空,则直接返回。
2.递归地中序遍历左子树。
3.访问当前节点。
4.递归地中序遍历右子树。
中序遍历的代码示例:```pythondef inorder(root):if root is None:returninorder(root.left)print(root.val)inorder(root.right)```三、后序遍历(Postorder Traversal)后序遍历是从左子树开始,按照左子树-右子树-根节点的顺序访问所有节点。
具体步骤如下:1.若树为空,则直接返回。
2.递归地后序遍历左子树。
3.递归地后序遍历右子树。
4.访问当前节点。
后序遍历的代码示例:```pythondef postorder(root):if root is None:returnpostorder(root.left)postorder(root.right)print(root.val)```以上是树的三种遍历方法的详细介绍及示例代码。
树的表示法字典解释
树是一种数据结构,它由若干个节点组成,这些节点通过边相连。
树的表示法有多种,其中比较常见的包括以下几种:
1. 儿子-兄弟表示法(孩子兄弟表示法),这种表示法通过每
个节点的指针来表示树的结构。
每个节点有两个指针,一个指向它
的第一个孩子节点,另一个指向它的下一个兄弟节点。
这种表示法
适合于一般的树,但不适合于二叉树。
2. 层次遍历表示法,这种表示法是按照树的层次结构来表示的,通常使用数组或者队列来表示。
从根节点开始,按照层次顺序依次
存储每个节点的数值,空节点用特定的符号表示。
这种表示法适合
于完全二叉树。
3. 括号表示法,这种表示法是通过括号和逗号来表示树的结构。
具体来说,可以使用前序遍历的方式,通过括号表示节点的嵌套关系。
例如,树 (A(B(C))(D)) 可以表示为 A(B(C))(D)。
树的表示法可以根据具体的应用场景和需要选择合适的方式。
每种表示法都有其适用的范围和特点,需要根据实际情况进行选择。
希望这些信息能够帮助你更好地理解树的表示法。
树形结构的例子树形结构是一种常见的数据结构,它由节点和边组成,用于表示具有层次关系的数据。
以下是一些树形结构的例子:1. 文件系统树:文件系统树是计算机文件系统的一种组织形式。
它以根目录为起点,每个目录都可以包含其他目录和文件。
通过文件系统树,用户可以方便地浏览和管理文件。
2. HTML文档树:HTML文档树用于表示网页的结构和内容。
它由一个根节点开始,每个节点都可以包含其他节点,形成层次关系。
通过HTML文档树,浏览器可以解析和渲染网页。
3. 组织机构树:组织机构树用于表示企业或组织的组织结构。
根节点代表整个组织,每个节点代表一个部门或岗位,节点之间的边表示上下级关系。
通过组织机构树,可以清晰地了解企业的组织架构。
4. 家谱树:家谱树用于表示家族的家族关系。
根节点代表始祖,每个节点代表一个人,节点之间的边表示父子关系。
通过家谱树,可以追溯和查找家族的成员和血缘关系。
5. 类型继承树:在面向对象编程中,类型继承树用于表示类的继承关系。
根节点代表基类,每个节点代表一个派生类,节点之间的边表示继承关系。
通过类型继承树,可以清晰地了解类的继承结构。
6. 商品分类树:在电商网站中,商品分类树用于表示商品的分类关系。
根节点代表整个商品分类体系,每个节点代表一个商品分类,节点之间的边表示上下级分类关系。
通过商品分类树,用户可以方便地浏览和搜索商品。
7. 语言家族树:在语言学中,语言家族树用于表示不同语言之间的关系。
根节点代表原始语言,每个节点代表一种语言,节点之间的边表示语言演化和分支关系。
通过语言家族树,可以研究和比较不同语言的历史和特点。
8. 系统调用树:在操作系统中,系统调用树用于表示不同系统调用的关系和层次。
根节点代表操作系统内核,每个节点代表一个系统调用,节点之间的边表示调用关系。
通过系统调用树,可以了解和使用不同系统调用的功能和接口。
9. 目录结构树:目录结构树用于表示文件或文件夹的组织关系。
根节点代表根目录,每个节点代表一个文件或文件夹,节点之间的边表示包含关系。
数据结构⼊门-树的遍历以及⼆叉树的创建树定义:1. 有且只有⼀个称为根的节点2. 有若⼲个互不相交的⼦树,这些⼦树本⾝也是⼀个树通俗的讲:1. 树是有结点和边组成,2. 每个结点只有⼀个⽗结点,但可以有多个⼦节点3. 但有⼀个节点例外,该节点没有⽗结点,称为根节点⼀、专业术语结点、⽗结点、⼦结点、根结点深度:从根节点到最底层结点的层数称为深度,根节点第⼀层叶⼦结点:没有⼦结点的结点⾮终端节点:实际上是⾮叶⼦结点度:⼦结点的个数成为度⼆、树的分类⼀般树:任意⼀个结点的⼦结点的个数都不受限制⼆叉树:任意⼀个结点的⼦结点个数最多是两个,且⼦结点的位置不可更改⼆叉数分类:1. ⼀般⼆叉数2. 满⼆叉树:在不增加树层数的前提下,⽆法再多添加⼀个结点的⼆叉树3. 完全⼆叉树:如果只是删除了满⼆叉树最底层最右边的连续若⼲个结点,这样形成的⼆叉树就是完全⼆叉树森林:n个互不相交的树的集合三、树的存储⼆叉树存储连续存储(完全⼆叉树)优点:查找某个结点的⽗结点和⼦结点(也包括判断有没有⼦结点)速度很快缺点:耗⽤内存空间过⼤链式存储⼀般树存储1. 双亲表⽰法:求⽗结点⽅便2. 孩⼦表⽰法:求⼦结点⽅便3. 双亲孩⼦表⽰法:求⽗结点和⼦结点都很⽅便4. ⼆叉树表⽰法:把⼀个⼀般树转化成⼀个⼆叉树来存储,具体转换⽅法:设法保证任意⼀个结点的左指针域指向它的第⼀个孩⼦,右指针域指向它的兄弟,只要能满⾜此条件,就可以把⼀个⼀般树转化为⼆叉树⼀个普通树转换成的⼆叉树⼀定没有右⼦树森林的存储先把森林转化为⼆叉树,再存储⼆叉树四、树的遍历先序遍历:根左右先访问根结点,再先序访问左⼦树,再先序访问右⼦树中序遍历:左根右中序遍历左⼦树,再访问根结点,再中序遍历右⼦树后续遍历:左右根后续遍历左⼦树,后续遍历右⼦树,再访问根节点五、已知两种遍历求原始⼆叉树给定了⼆叉树的任何⼀种遍历序列,都⽆法唯⼀确定相应的⼆叉树,但是如果知道了⼆叉树的中序遍历序列和任意的另⼀种遍历序列,就可以唯⼀地确定⼆叉树已知先序和中序求后序先序:ABCDEFGH中序:BDCEAFHG求后序:这个⾃⼰画个图体会⼀下就可以了,⾮常简单,这⾥简单记录⼀下1. ⾸先根据先序确定根,上⾯的A就是根2. 中序确定左右,A左边就是左树(BDCE),A右边就是右树(FHG)3. 再根据先序,A左下⾯就是B,然后根据中序,B左边没有,右边是DCE4. 再根据先序,B右下是C,根据中序,c左下边是D,右下边是E,所以整个左树就确定了5. 右树,根据先序,A右下是F,然后根据中序,F的左下没有,右下是HG,6. 根据先序,F右下为G,然后根据中序,H在G的左边,所以G的左下边是H再来⼀个例⼦,和上⾯的思路是⼀样的,这⾥就不详细的写了先序:ABDGHCEFI中序:GDHBAECIF已知中序和后序求先序中序:BDCEAFHG后序:DECBHGFA这个和上⾯的思路是⼀样的,只不过是反过来找,后序找根,中序找左右树简单应⽤树是数据库中数据组织⼀种重要形式操作系统⼦⽗进程的关系本⾝就是⼀棵树⾯向对象语⾔中类的继承关系哈夫曼树六、⼆叉树的创建#include <stdio.h>#include <stdlib.h>typedef struct Node{char data;struct Node * lchild;struct Node * rchild;}BTNode;/*⼆叉树建⽴*/void BuildBT(BTNode ** tree){char ch;scanf("%c" , &ch); // 输⼊数据if(ch == '#') // 如果这个节点的数据是#说明这个结点为空*tree = NULL;else{*tree = (BTNode*)malloc(sizeof(BTNode));//申请⼀个结点的内存 (*tree)->data = ch; // 将数据写⼊到结点⾥⾯BuildBT(&(*tree)->lchild); // 递归建⽴左⼦树BuildBT(&(*tree)->rchild); // 递归建⽴右⼦树}}/*⼆叉树销毁*/void DestroyBT(BTNode *tree) // 传⼊根结点{if(tree != NULL){DestroyBT(tree->lchild);DestroyBT(tree->rchild);free(tree); // 释放内存空间}}/*⼆叉树的先序遍历*/void Preorder(BTNode * node){if(node == NULL)return;else{printf("%c ",node->data );Preorder(node->lchild);Preorder(node->rchild);}}/*⼆叉树的中序遍历*/void Inorder(BTNode * node){if(node == NULL)return;else{Inorder(node->lchild);printf("%c ",node->data );Inorder(node->rchild);}}/*⼆叉树的后序遍历*/void Postorder(BTNode * node){if(node == NULL)return;else{Postorder(node->lchild);Postorder(node->rchild);printf("%c ",node->data );}}/*⼆叉树的⾼度树的⾼度 = max(左⼦树⾼度,右⼦树⾼度) +1*/int getHeight(BTNode *node){int Height = 0;if (node == NULL)return 0;else{int L_height = getHeight(node->lchild);int R_height = getHeight(node->rchild);Height = L_height >= R_height ? L_height +1 : R_height +1; }return Height;}int main(int argc, char const *argv[]){BTNode * BTree; // 定义⼀个⼆叉树printf("请输⼊⼀颗⼆叉树先序序列以#表⽰空结点:");BuildBT(&BTree);printf("先序序列:");Preorder(BTree);printf("\n中序序列:");Inorder(BTree);printf("\n后序序列:");Postorder(BTree);printf("\n树的⾼度为:%d" , getHeight(BTree));return 0;}// ABC##DE##F##G##。
数据结构二叉树的基本操作代码x#include<iostream>using namespace std;//二叉树的结构struct TreeNode{int data;//节点的值TreeNode *left;//指向左子树TreeNode *right;//指向右子树};//插入节点void insert(TreeNode *&tree, int val){if(tree == NULL){tree = new TreeNode;tree->data = val;tree->left = tree->right = NULL;}else if(val<=tree->data)//小于根节点的值则插入到左子树 insert(tree->left, val);else if(val>tree->data)//大于根节点的值则插入到右子树 insert(tree->right,val);}//查找节点TreeNode* find(TreeNode *tree,int val){if (tree == NULL)//树为空,无法查找return NULL;else if (val == tree->data)//值和节点的值相等,返回该节点return tree;else if (val < tree->data)//值小于节点的值,查找左子树 return find(tree->left,val);else if (val > tree->data)//值大于节点的值,查找右子树 return find(tree->right,val);elsereturn NULL;//无法查找}//遍历二叉树//先序遍历void preOrder(TreeNode *tree){if(tree != NULL){cout<< tree->data <<'t'; //先访问根节点preOrder(tree->left); //再遍历左子树 preOrder(tree->right); //最后遍历右子树 }}//中序遍历void inOrder(TreeNode *tree){if(tree != NULL){inOrder(tree->left); //先遍历左子树 cout<< tree->data <<'t'; //再访问根节点inOrder(tree->right); //最后遍历右子树 }}//后序遍历void postOrder(TreeNode *tree){if(tree != NULL){postOrder(tree->left); //先遍历左子树 postOrder(tree->right); //再遍历右子树 cout<< tree->data <<'t'; //最后访问根节点 }}//查找最大值TreeNode* findMax(TreeNode *tree){if(tree == NULL)return NULL;else if(tree->right == NULL)return tree;elsereturn findMax(tree->right);}//查找最小值TreeNode* findMin(TreeNode *tree){if(tree == NULL)return NULL;else if(tree->left == NULL)return tree;elsereturn findMin(tree->left);}//删除节点void remove(TreeNode *&tree, int val){if(tree == NULL)return;else if(val < tree->data)remove(tree->left, val);else if(val > tree->data)remove(tree->right, val);else//找到要删除的节点{if(tree->left != NULL && tree->right != NULL)//左右子树均不为空{TreeNode *temp = tree;TreeNode *max = findMax(tree->left);//查找左子树的最大结点tree->data = max->data;//将最大结点的值替换到要删除的节点remove(temp->left, max->data);//将最大结点删掉}else//只有一边的子节点不为空或者左右节点都为空{TreeNode *temp = tree;if(tree->left == NULL)//如果左节点为空,就将右节点提升 tree = tree->right;else if(tree->right == NULL)//如果右节点为空,就将左节点提升tree = tree->left;delete temp;//删掉要删除的节点}}}int main(){TreeNode *tree = NULL; //声明一个空树int arr[10] = {12, 3, 4, 6, 7, 9, 10, 5, 2, 8};for(int i=0; i<10; i++){insert(tree, arr[i]);//把数组元素插入到树当中}cout<<'先序遍历:';preOrder(tree);cout<<endl;cout<<'中序遍历:';inOrder(tree);cout<<endl;cout<<'后序遍历:';postOrder(tree);cout<<endl;cout<<'查找节点数据:4';TreeNode *findNode = find(tree, 4);if(findNode != NULL)//如果节点存在cout<<'找到了,节点的值是:'<<findNode->data;else//如果节点不存在cout<<'没有找到';cout<<endl;cout<<'查找树的最大值:'<<findMax(tree)->data<<endl; cout<<'查找树的最小值:'<<findMin(tree)->data<<endl; cout<<'删除节点:。
树的三种遍历方式树是一种非常重要的数据结构,它在计算机科学中应用广泛。
树可以用于搜索、排序、数据表、文件系统等诸多领域。
而树的遍历方式,则是在树中搜索数据的一种方法。
树的遍历方式有三种,分别是前序遍历、中序遍历和后序遍历。
这三种遍历方式在树的数据结构中有着重要的作用,它们可以用来检索所有节点的信息。
下面我们将对它们一一进行介绍。
1.前序遍历前序遍历也称为先序遍历,它的顺序是根节点->左子树->右子树。
它的算法描述如下:前序遍历的递归算法实现:void PreOrderTraversal(TraversalNode T){ if (T) { visit(T); PreOrderTraversal(T->left); PreOrderTraversal(T->right); } }前序遍历的非递归算法实现:void PreOrderTraversal(TraversalNode T){ while (T || !StackIsEmpty(S)) { while (T) { visit(T); push(Stack,T); T = T->left; } if(!StackIsEmpty(S)) { T = pop(Stack);T = T->right; } } }2.中序遍历中序遍历的顺序是左子树->根节点->右子树。
它的算法描述如下:中序遍历的递归算法实现:void InOrderTraversal(TraversalNode T) { if(T) { InOrderTraversal(T->left);visit(T);InOrderTraversal(T->right); } }中序遍历的非递归算法实现:void InOrderTraversal(TraversalNode T){ while (T || !StackIsEmpty(S)) { while(T) { push(Stack, T); T =T->left; } if (!StackIsEmpty(S)){ T = pop(Stack); visit(T); T = T->right; } } }3.后序遍历后序遍历的顺序是左子树->右子树->根节点。
Vue循环遍历树形结构Vue.js 是一种流行的前端框架,使开发者能够构建交互式的用户界面。
在Vue中,我们经常需要处理树形结构的数据,例如文件夹嵌套、评论回复、组织结构等。
本文将介绍如何使用Vue来循环遍历树形结构并展示在界面上。
为什么需要循环遍历树形结构?树形结构具有层次化的特点,每个节点可以有多个子节点。
循环遍历树形结构可以实现以下功能:1.显示树形结构数据:将树形结构的数据在用户界面中展示出来,以便用户能够更好地理解和操作数据。
2.遍历树形结构:对树形结构的每个节点进行遍历操作,例如查找指定节点、计算节点数量、统计节点属性等。
3.操作树形结构:对树形结构的节点进行增删改操作,例如添加子节点、删除节点、修改节点属性等。
在Vue中循环遍历树形结构在Vue中,我们可以使用v-for指令来循环遍历树形结构,然后用递归的方式处理子节点。
1. 准备树形结构数据首先,我们需要准备一个树形结构的数据,例如:data() {return {treeData: [{name: '节点1',children: [{name: '节点1-1',children: [{name: '节点1-1-1',children: []},{name: '节点1-1-2',children: []}]},{name: '节点1-2',children: []}]},{name: '节点2',children: []}]}}2. 创建递归组件接下来,我们需要创建一个递归组件来处理树形结构的数据。
在Vue中,我们可以使用<template>标签声明一个组件,并在组件中递归调用自身来处理子节点。
<template><div><ul><li v-for="node in treeData">{{ }}<tree-node :treeData="node.children"></tree-node></li></ul></div></template><script>export default {name: 'TreeNode',props: {treeData: {type: Array,default: () => []}},components: {'tree-node': this}}</script>在上面的代码中,我们使用v-for指令循环遍历树形结构的每个节点,并使用递归调用<tree-node>组件处理子节点。
二叉树的顺序存储结构代码介绍二叉树是一种常用的数据结构,它由节点组成,每个节点最多有两个子节点。
在计算机中,我们通常使用顺序存储结构来表示二叉树。
顺序存储结构是将二叉树的节点按照从上到下、从左到右的顺序依次存储在一个数组中。
本文将详细介绍二叉树的顺序存储结构代码,包括初始化、插入节点、删除节点以及遍历等操作。
二叉树的顺序存储结构代码实现初始化二叉树首先,我们需要定义一个数组来存储二叉树的节点。
假设数组的大小为n,则二叉树的最大节点数量为n-1。
# 初始化二叉树,将数组中所有元素置为空def init_binary_tree(n):binary_tree = [None] * nreturn binary_tree插入节点在二叉树的顺序存储结构中,节点的插入操作需要保持二叉树的特性,即左子节点小于父节点,右子节点大于父节点。
插入节点的算法如下:1.找到待插入位置的父节点索引parent_index。
2.如果待插入节点小于父节点,将其插入到父节点的左子节点位置,即数组索引2*parent_index+1处。
3.如果待插入节点大于父节点,将其插入到父节点的右子节点位置,即数组索引2*parent_index+2处。
# 插入节点def insert_node(binary_tree, node):index = 0 # 当前节点的索引值,初始值为根节点的索引值while binary_tree[index] is not None:if node < binary_tree[index]:index = 2 * index + 1 # 插入到左子节点else:index = 2 * index + 2 # 插入到右子节点binary_tree[index] = node删除节点删除节点需要保持二叉树的特性,即在删除节点后,仍然满足左子节点小于父节点,右子节点大于父节点的条件。
删除节点的算法如下:1.找到待删除节点的索引delete_index。
数据结构中的树、图、查找、排序在计算机科学中,数据结构是组织和存储数据的方式,以便能够有效地对数据进行操作和处理。
其中,树、图、查找和排序是非常重要的概念,它们在各种算法和应用中都有着广泛的应用。
让我们先来谈谈树。
树是一种分层的数据结构,就像是一棵倒立的树,有一个根节点,然后从根节点向下延伸出许多分支节点。
比如一个家族的族谱,就可以用树的结构来表示。
最上面的祖先就是根节点,他们的后代就是分支节点。
在编程中,二叉树是一种常见的树结构。
二叉树的每个节点最多有两个子节点,分别称为左子节点和右子节点。
二叉搜索树是一种特殊的二叉树,它具有特定的性质,即左子树中的所有节点值都小于根节点的值,而右子树中的所有节点值都大于根节点的值。
这使得在二叉搜索树中查找一个特定的值变得非常高效。
二叉搜索树的插入和删除操作也相对简单。
插入时,通过比较要插入的值与当前节点的值,确定往左子树还是右子树移动,直到找到合适的位置插入新节点。
删除节点则稍微复杂一些,如果要删除的节点没有子节点,直接删除即可;如果有一个子节点,用子节点替换被删除的节点;如果有两个子节点,通常会找到右子树中的最小节点来替换要删除的节点,然后再删除那个最小节点。
接下来,我们聊聊图。
图是由顶点(也称为节点)和边组成的数据结构。
顶点代表对象,边则表示顶点之间的关系。
比如,社交网络中的用户可以看作顶点,用户之间的好友关系就是边。
图可以分为有向图和无向图。
有向图中的边是有方向的,就像单行道;无向图的边没有方向,就像双向车道。
图的存储方式有邻接矩阵和邻接表等。
邻接矩阵用一个二维数组来表示顶点之间的关系,如果两个顶点之间有边,对应的数组元素为 1,否则为 0。
邻接表则是为每个顶点建立一个链表,链表中存储与该顶点相邻的顶点。
图的遍历是图算法中的重要操作,常见的有深度优先遍历和广度优先遍历。
深度优先遍历就像是沿着一条路一直走到底,然后再回头找其他路;广度优先遍历则是先访问距离起始顶点近的顶点,再逐步扩展到更远的顶点。
java树形结构数据遍历所有分⽀现在有⼀个树形结构的元素集合map list,要求遍历该树的所有分⽀代码如下:package com.inslink.controller.element;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;import java.util.Collections;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Set;import ermodel.Cell;import ermodel.Row;import ermodel.Sheet;import ermodel.Workbook;import ermodel.XSSFWorkbook;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.baomidou.mybatisplus.service.IService;import com.inslink.controller.GenericController;import com.inslink.model.element.core.Element;import com.inslink.service.element.ElementService;public class RobotLogicTreeController {@Autowiredprivate ElementService elementService;private static boolean flag = true;private static List<List<Map<String, Object>>> excellist = new ArrayList<List<Map<String,Object>>>();private static Map<String, Object> parentMap = new HashMap<String, Object>();private static List<Map<String,Object>> mlist = new ArrayList<Map<String,Object>>();//遍历所有分⽀public static List<Map<String,Object>> getSonMap(Map<String,Object> parentMap1,List<Map<String,Object>> treeElements,List<Map<String,Object>> list) { if (parentMap1.get("parent")==null) {list.add(parentMap1);}for (int i=0;i<treeElements.size();i++) {Map<String,Object> map = treeElements.get(i);if (map.get("parent")!=null && parentMap1.get("id").toString().equals(map.get("parent").toString())) {flag = true;list.add(map);getSonMap(map,treeElements,list);}//不存在⼦节点else {flag = false;continue;}if (!flag) {if (list.size()>1) {//判断新增的list中的在树中是否存在⼦节点boolean exist = false;for (Map<String,Object> s : mlist) {System.out.println(s.get("parent"));if (s.get("parent")!=null && s.get("parent").toString().equals(map.get("id").toString())) { exist = true;break;}}if (!exist) {excellist.add(list);}}//删除此分⽀上所有只有⼀个⼦节点的节点或末⽀节点treeElements.remove(map);list = new ArrayList<>();getSonMap(parentMap,treeElements,list);break;}}return list;}@Overrideprotected IService<Element> getService() {// TODO Auto-generated method stubreturn null;}public static void main(String[] args) {Map<String,Object> map1 = new HashMap<String,Object>();map1.put("name", "乳腺");map1.put("level", "0");map1.put("id", "1");map1.put("parent", null);Map<String,Object> map2 = new HashMap<String,Object>();map2.put("name", "乳腺1");map2.put("level", "1");map2.put("id", "2");map2.put("parent", "1");Map<String,Object> map3 = new HashMap<String,Object>();map3.put("name", "乳腺2-1");map3.put("level", "2");map3.put("id", "3");map3.put("parent", "2");Map<String,Object> map4 = new HashMap<String,Object>();map4.put("name", "乳腺2-2");map4.put("level", "2");map4.put("id", "4");map4.put("parent", "2");Map<String,Object> map5 = new HashMap<String,Object>();map5.put("name", "乳腺2-3");map5.put("level", "2");map5.put("id", "5");map5.put("parent", "2");Map<String,Object> map6 = new HashMap<String,Object>();map6.put("name", "乳腺3-1");map6.put("level", "3");map6.put("id", "6");map6.put("parent", "3");Map<String,Object> map8 = new HashMap<String,Object>();map8.put("name", "乳腺3-8");map8.put("level", "3");map8.put("id", "8");map8.put("parent", "3");Map<String,Object> map7 = new HashMap<String,Object>();map7.put("name", "乳腺3-2");map7.put("level", "3");map7.put("id", "7");map7.put("parent", "5");List<Map<String,Object>> treeElements = new ArrayList<Map<String,Object>>();treeElements.add(map1);treeElements.add(map2);treeElements.add(map3);treeElements.add(map4);treeElements.add(map5);treeElements.add(map6);treeElements.add(map7);treeElements.add(map8);// Map<String,Object> treeMap = new HashMap<String,Object>();// map = sortTreeMap(map1, treeElements,treeMap);mlist = new ArrayList<Map<String,Object>>();mlist = new ArrayList<Map<String,Object>>((Collection<? extends Map<String, Object>>) Arrays.asList(new Map[treeElements.size()])); Collections.copy(mlist, treeElements);parentMap = map1;List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();list = getSonMap(parentMap, treeElements,list);for ( List<Map<String, Object>> slist : excellist) {System.out.println("=====");for (Map<String,Object> smap : slist) {System.out.println(smap.get("id"));}}}}。
家谱管理系统——C语言(数据结构)目的和要求:树形结构是一种非常重要的非线性结构,它用于描述数据元素之间的层次关系,人类家谱是树形结构的典型体现,通过此项训练让学生掌握树形结构的知识;使学生重点掌握树与二叉树的转换,二叉树的存储和遍历,和二叉树相关的一些运算;要求完成家谱信息的录入和保存,任意成员的查找及某一成员祖先、子孙、兄弟、堂兄弟的查找。
排答疑和辅导。
完整代码:#include <stdio.h>#include <stdlib.h>#include <string.h>int MATEFLAG=0; //是否入赘或嫁入这家的,1表示为是,0表示否typedef struct TreeNode//树节点定义{int Num; //保存此人儿女个数char Name[20]; //保存此人姓名char Kind; //保存此人性别,男M,女Fstruct TreeNode * NextNode[20]; //保存此人的儿女,NextNode[0]里存放配偶的地址struct TreeNode * Parent; //保存此节点的父节点}TreeNode;void CreatTree(TreeNode *Tree);//创建树void OutPutAll(TreeNode *Tree);//输出树TreeNode * SearchTree(TreeNode *Tree,char name[],int length);void MainMenu(TreeNode *Tree);void SubMenue1(TreeNode * Tree);void SubMenue2(TreeNode *Tree);void Change(TreeNode * Tree);void AddNew(TreeNode * Tree);void OutPutMessage(TreeNode * Tree,char name[],int length);//主函数void main(){TreeNode *Tree;//产生根节点Tree=(TreeNode *)malloc(sizeof(TreeNode));Tree->Parent =NULL;strcpy(Tree->Name,"0");MainMenu(Tree);//显示主菜单}//添加新的成员void AddNew(TreeNode * Tree){SubMenue2(Tree);//添加新成员界面}//显示添加家庭信息的界面void SubMenue2(TreeNode *Tree){char c;int num;char name[20];TreeNode * NewNode;getchar();while(1){system("cls");printf("请选择你的操作\n");printf("A:添加某个人的子女的信息\n");printf("B:添加某个人配偶的信息\n");printf("C:退出\n");printf("请选择相应功能:\n");c=getchar();switch(c){case 'A': //添加子女信息printf("请输入那个人的名字:\n");scanf("%s",name);Tree=SearchTree(Tree,name,20);//在家谱里查找这个人if(Tree==NULL){printf("该家谱图中没有%s这个人的信息请确认是否输入错误\n",name);break;}if(Tree->Parent==NULL&&Tree->NextNode[0]==NULL||Tree->Parent!=NULL&&Tree->N ame!=Tree->Parent->NextNode[0]->Name){printf("至今还没有配偶请先添加配偶\n",Tree->Name);break;}if(Tree->Parent==NULL&&(Tree->Num>20||Tree->Num<0))Tree->Num=0;if(MATEFLAG==1)Tree=Tree->Parent;NewNode=(TreeNode *)malloc(sizeof(TreeNode));printf("请输入添加人员姓名:\n");scanf("%s",NewNode->Name);printf("请输入添加人员性别女F男M:\n");scanf("%1s",&NewNode->Kind);num=Tree->Num;NewNode->NextNode[0]=(TreeNode *)malloc(sizeof(TreeNode));NewNode->NextNode[0]=NULL;NewNode->Num=0;NewNode->Parent=Tree;Tree->NextNode[num+1]=NewNode;Tree->Num=Tree->Num+1;printf("子女的信息添加成功\n");break;case 'B':printf("请输入那个人的名字:\n");scanf("%s",name);Tree=SearchTree(Tree,name,20);if(Tree->Parent!=NULL&&strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)==0||T ree->NextNode[0]!=NULL){printf("已经有了配偶\n");break;}if(Tree==NULL){printf("该家谱图中没有%s这个人的信息请确认\n",name);break;}NewNode=(TreeNode *)malloc(sizeof(TreeNode));printf("请输入添加人员姓名:\n");scanf("%s",NewNode->Name);printf("请输入添加人员性别女F男M:\n");scanf("%1s",&NewNode->Kind);NewNode->Parent=Tree;Tree->NextNode[0]=NewNode;break;case 'C':printf("本项服务到此结束\n");break;case '\n':break;default:printf("对不起!你的选择错误\n");break;}if (c=='C'||c=='c')break;printf("请按Enter键继续操作\n");getchar();getchar();}}//修改某个人的信息void Change(TreeNode * Tree){char name[20];TreeNode * NewNode;printf("请输入你要修改的人的信息:\n");scanf("%s",name);NewNode=SearchTree(Tree,name,20);if(NewNode==NULL){printf("该家谱图中没有%s这个人的信息请确认是否输入错误\n",name); return;}else{SubMenue1(NewNode);}}//输出副菜单void SubMenue1(TreeNode * Tree){char c;int flag,i;char name[20];char Parent[2][20];TreeNode * NewNode;getchar();while(1){system("cls");printf("请选择你的操作\n");printf("A:修改个人的信息\n");printf("B:修改父母的信息\n");printf("C:修改兄弟姐妹的信息\n");printf("D:修改子女的信息\n");printf("E:修改配偶的信息\n");printf("F:退出\n");c=getchar();switch(c){case 'A':printf("请输入修改的姓名:如果不需要修改就输入'0'然后按Enter键继续\n");scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->Name,name);printf("是否要修改性别:如果需要就输入'1'不需要修改就输入'0'然后按Enter键继续\n");scanf("%d",&flag);if (flag==1){if(Tree->Kind=='F'||Tree->Kind=='f')Tree->Kind='M';else Tree->Kind='F';}printf("个人信息修改成功\n");break;case 'B':if(Tree->Parent==NULL) //判断是不是头节点{printf("是这个家谱图里最顶端的人没有父母信息!\n",name);break;}if (MATEFLAG==1) //判断是不是入赘或加入此间的{if(Tree->Kind=='F'||Tree->Kind=='f'){printf("她是嫁入此间的所以父母信息不在家谱内包括\n");}else{printf("他是入赘此间的所以父母信息不在家谱内包括\n");}break;}if(Tree->Parent->Kind=='F'||Tree->Parent->Kind=='f'){strcpy(Parent[0],"母亲");strcpy(Parent[1],"父亲");}else{strcpy(Parent[0],"父亲");strcpy(Parent[1],"母亲");}printf("请输入%s要修改的姓名:如果不需要修改就输入'0'然后按Enter键继续\n",Parent[0]);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->Parent->Name,name);printf("请输入%s要修改的姓名:如果不需要修改就输入'0'然后按Enter键继续\n",Parent[1]);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->Parent->NextNode[0]->Name,name);printf("父母的信息修改成功\n");break;case 'C':NewNode=Tree->Parent;if(NewNode==NULL) //判断是不是头节点{printf("是这个家谱图里最顶端的人没有兄弟姐妹信息!\n",name);break;}if (MATEFLAG==1) //判断是不是入赘或嫁入这家的{if(Tree->Kind=='F'||Tree->Kind=='f'){printf("她是嫁入此间的所以兄弟姐妹信息不在家谱内包括\n");}else{printf("他是入赘此间的所以兄弟姐妹信息不在家谱内包括\n");}break;}if(NewNode->Num==1){printf("没有兄弟姐妹\n");break;}else{for(i=1;i<=NewNode->Num;i++){if(NewNode->NextNode[i]->Name!=Tree->Name){printf("请输入%s修改的姓名:如果不需要修改就输入'0'然后按Enter键继续\n",NewNode->NextNode[i]->Name);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(NewNode->NextNode[i]->Name,name);printf("是否要修改性别:如果需要就输入'1'不需要修改就输入'0'然后按Enter键继续\n");scanf("%d",&flag);if (flag==1){if(NewNode->NextNode[i]->Kind=='G'||NewNode->NextNode[i]->Kind=='g') NewNode->NextNode[i]->Kind='B';else NewNode->NextNode[i]->Kind='G';}}}}printf("兄弟姐妹的信息修改成功\n");break;case 'D':if(Tree->Num==0){printf("至今还没有子女\n");break;}if (Tree->Parent !=NULL)if (strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)==0) //如果他是入赘或者是嫁入的就需用配偶节点完成修改{Tree=Tree->Parent;}for(i=1;i<=Tree->Num;i++){printf("请输入%s修改的姓名:如果不需要修改就输入'0'然后按Enter键继续\n",Tree->NextNode[i]->Name);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->NextNode[i]->Name,name);printf("是否要修改性别:如果需要就输入'1'不需要修改就输入'0'然后按Enter键继续\n");scanf("%d",&flag);if (flag==1){if(Tree->NextNode[i]->Kind=='F'||Tree->NextNode[i]->Kind=='f')Tree->NextNode[i]->Kind='M';else Tree->NextNode[i]->Kind='F';}}printf("子女的信息修改成功\n");break;case 'E':if(Tree->Parent!=NULL){if(Tree->NextNode[0]==NULL&&strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)!=0) {printf("至今还没有配偶\n");break;}if (strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)==0){printf("\n\n\t请输入%s修改的姓名:如果不需要修改就输入'0'然后按Enter键继续\n\t",Tree->Parent->Name);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->Parent->Name,name);}else{printf("\n\n\t请输入%s修改的姓名:如果不需要修改就输入'0'然后按Enter键继续\n\t",Tree->NextNode[0]->Name);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->NextNode[0]->Name,name);}}else{if(Tree->NextNode[0]==NULL)printf("至今还没有配偶\n");else{printf("\n\n\t请输入%s修改的姓名:如果不需要修改就输入'0'然后按Enter键继续\n\t",Tree->NextNode[0]->Name);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->NextNode[0]->Name,name);}}printf("配偶的信息修改成功\n");break;case 'F':printf("本项服务到此结束\n");break;case '\n':break;default:printf("对不起!你的选择错误\n");break;}if (c=='F'||c=='f')break;printf("请按Enter键继续操作\n");getchar();getchar();}}//输出主菜单void MainMenu(TreeNode *Tree){char c;//用于接受用户输入的选项char name[20];while(1){system("cls");//清屏printf("★★★★★★★★★★★★★欢迎进入家谱管理系统★★★★★★★★★★★\n\n\n");printf(" ◆◆菜单◆◆ \n\n");printf(" ●输入家谱信息---------------------1\n");printf(" ●查找家族成员---------------------2\n");printf(" ●添加家族成员---------------------3\n");printf(" ●输出家谱信息---------------------4\n");printf(" ●修改成员信息---------------------5\n");printf(" ●退出-----------------------------6\n");printf("\n\n★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★\n");printf("请选择相应的功能:\n");c=getchar();switch(c){case '1': TreeNode * NewNode; NewNode=(TreeNode *)malloc(sizeof(TreeNode));//建立新节点printf("请输入姓名:"); scanf("%s",Tree->Name);//给节点姓名赋值 printf("请输入性别(女F,男M):"); getchar();//给性别赋值scanf("%c",&(Tree->Kind)); // Tree->Parent=NewNode; Tree->Parent=NULL; CreatTree(Tree); printf("家谱图已经建立成功\n"); printf("请按Enter键继续操作\n"); getchar(); break; case '2': if(strcmp(Tree->Name,"0")==0) { printf("家谱图还未建立请先建立\n"); getchar(); break; } printf("请输入你要查找的人的姓名:\n"); scanf("%s",name); OutPutMessage(SearchTree(Tree,name,20),name,20); getchar(); break; case '3': if(strcmp(Tree->Name,"0")==0) { printf("家谱图还未建立请先建立\n"); getchar(); break; } AddNew(Tree); getchar(); break; case '4': if(strcmp(Tree->Name,"0")==0) { printf("家谱图还未建立请先建立\n"); getchar(); break; }printf("整个家谱的主要信息如下:\n");OutPutAll(Tree);getchar();break;case '5':if(strcmp(Tree->Name,"0")==0){printf("家谱图还未建立请先建立\n");getchar();break;}Change(Tree);getchar();break;case '6':printf("本程序结束,欢迎下次使用。
树形结构样式
树形结构样式通常使用缩进来表示层级关系,每一层都比上一层多缩进一个固定量。
以下是一个简单的示例:
```
根节点
├─ 子节点1
│ ├─ 子节点1.1
│ └─ 子节点1.2
├─ 子节点2
└─ 子节点3
└─ 子节点3.1
```
在这个示例中,根节点是位于顶部的节点。
子节点1、子节点2和子节点3是根节点的直接子节点。
子节点3包含一个名为子节点3.1的子节点,而子节点1具有两个子节点子节点1.1和子节点1.2。
这种样式的树形结构可以方便地表示层级关系,并且易于阅读和理解。
每个子节点都与其父节点在同一列上,并且通过垂直线条连接。
请注意,上述示例只是一种常见的树形结构样式之一。
树形结构的样式可以根据需求和个人偏好进行定制和调整。
树形结构需要的几个字段组成
树形结构是一种层次化的数据结构,通常用于表示具有父子关系的数据。
在实现树形结构时,通常需要以下几个字段:
1. ID字段,用于唯一标识树中的每个节点。
每个节点都有一个唯一的ID,可以用来区分不同的节点。
2. ParentID字段,用于表示节点之间的父子关系。
每个节点除了根节点外,都有一个父节点,通过ParentID字段可以确定节点的父节点是谁。
3. Name或者Value字段,用于存储节点的值或者名称。
这个字段可以根据具体的应用场景来确定,用于描述节点所代表的具体数据。
4. Level字段,有时候会包含一个表示节点所处层级的字段。
根节点通常属于第一层,其子节点属于第二层,以此类推。
5. 其他辅助字段,根据具体需求,可能还需要其他辅助字段来辅助实现树形结构的操作,比如排序字段、路径字段等。
这些字段组成了树形结构的基本元素,通过它们可以清晰地表示出树中节点之间的关系,实现对树形数据的存储和操作。
当然,具体的实现方式还取决于具体的应用场景和编程语言的特性。
树形结构编辑操作流程树形结构是一种常见的数据结构,它由节点和边组成,节点之间通过边相连,形成了层次关系。
在实际应用中,我们经常需要对树形结构进行编辑操作,包括插入、删除、修改等操作。
下面我们来详细介绍一下树形结构的编辑操作流程。
首先,我们需要了解树形结构的基本概念。
树形结构由根节点、子节点和叶节点组成,根节点是整个树的起始节点,子节点是根节点的直接后继节点,叶节点是没有子节点的节点。
在编辑操作中,我们通常需要对这些节点进行增删改查操作。
插入操作是对树形结构进行修改的一种常见操作。
插入操作可以在树的任意位置插入一个新的节点,使得树的结构发生变化。
插入操作的流程通常包括以下几个步骤:首先确定要插入的位置,然后创建一个新的节点,并将其插入到指定位置。
最后更新树的结构,确保新节点被正确插入。
删除操作是对树形结构进行修改的另一种常见操作。
删除操作可以删除树中的任意节点,使得树的结构发生变化。
删除操作的流程通常包括以下几个步骤:首先确定要删除的节点,然后删除该节点及其所有子节点。
最后更新树的结构,确保删除操作的正确执行。
修改操作是对树形结构进行修改的另一种常见操作。
修改操作可以修改树中的任意节点的值,使得树的结构保持不变。
修改操作的流程通常包括以下几个步骤:首先确定要修改的节点,然后修改该节点的值。
最后更新树的结构,确保修改操作的正确执行。
除了插入、删除、修改操作外,树形结构还可以进行查找、遍历等操作。
查找操作可以在树中查找指定节点的值,遍历操作可以按照某种顺序遍历树中的所有节点。
这些操作都是对树形结构进行编辑的重要操作,可以帮助我们更好地理解和管理树形结构。
总的来说,树形结构的编辑操作流程包括插入、删除、修改、查找、遍历等操作,每种操作都有其特定的流程和步骤。
通过对树形结构的编辑操作,我们可以更好地管理和利用树形结构,实现数据的有效组织和管理。
希望以上内容对您有所帮助。
#include <stdio.h>#include <stdlib.h>#define TElemType inttypedef struct BiTNode {TElemType data;struct BiTNode *lchild, *rchild;} BiTNode, *BiTree;typedef BiTree DataType;typedef struct queuenode{DataType data;struct queuenode *next;} QueueNode;//LINKQUEUE//HEAD POINTER, AND REAR POINTER ARE A V ALIBALE typedef struct {QueueNode *front;QueueNode *rear;} LinkQueue;int InitQueue(LinkQueue *Q);int DestroyQueue(LinkQueue *Q);int QueueEmpty(LinkQueue Q);int EnQueue(LinkQueue *Q, DataType e);DataType DeQueue(LinkQueue *Q);int CreateBiTree(BiTree *T);int PreOrderTraverse(BiTree T, int (*visit)(TElemType e));int PreOrderTraverse2(BiTree T, int (*visit)(TElemType e));int InOrderTraverse(BiTree T, int (*visit)(TElemType e));int InOrderTraverse2(BiTree T, int (*visit)(TElemType e));int PostOrderTraverse(BiTree T, int (*visit)(TElemType e));int PostOrderTraverse2(BiTree T, int (*visit)(TElemType e)); int LevelOrderTraverse(BiTree T, int (*visit)(TElemType e)); int printElem(TElemType e);int InitBiTree(BiTree *T);int DestroyBiTree(BiTree *T);int ClearBiTree(BiTree *T);int BiTreeEmpty(BiTree T);int BiTreeDepth(BiTree T);BiTNode *Parent(BiTree T, BiTNode *e);BiTNode *LeftChild(BiTree T, BiTNode *e);BiTNode *RightChild(BiTree T, BiTNode *e);BiTNode *LeftSibling(BiTree T, BiTNode *e);BiTNode *RightSibling(BiTree T, BiTNode *e);int InsertChild(BiTree T, BiTNode *p, int LR, BiTree C);int DeleteChild(BiTree T, BiTNode *p, int LR);int CountLeaf(BiTree T);int CreateBiTreeByPreInOrder(BiTree *T, int preorder[], int *idx,int inorder[], int low, int high,int length);int main(){BiTree bitree,bitree2;InitBiTree(&bitree);InitBiTree(&bitree2);printf("input tree 1:\n");CreateBiTree2(&bitree);printf("PreOrderTraverse:\n");PreOrderTraverse(bitree, printElem);printf("\n");printf("InOrderTraverse:\n");InOrderTraverse(bitree, printElem);printf("\n");printf("PostOrderTraverse:\n");PostOrderTraverse(bitree, printElem);printf("\n");printf("LevelOrderTraverse:\n");LevelOrderTraverse(bitree, printElem);printf("\n");printf("Depth is %d.\n", BiTreeDepth(bitree));printf("Count leaf is %d.\n", CountLeaf(bitree));DestroyBiTree(&bitree);DestroyBiTree(&bitree2);}int CreateBiTree(BiTree *T){int num;scanf("%d", &num);if (num == 0)*T = NULL;else {*T = malloc(sizeof(BiTNode));if (*T == NULL)return 0;(*T)->data = num;if (!CreateBiTree(&(*T)->lchild)) return 0;if (!CreateBiTree(&(*T)->rchild)) return 0;}return 1;}int PreOrderTraverse(BiTree T, int (*visit)(TElemType e)) {if (T) {//visit rootif (!(*visit)(T->data)) return 0;//visit left treeif (!PreOrderTraverse(T->lchild, visit)) return 0;//visit right treeif (!PreOrderTraverse(T->rchild, visit)) return 0;}return 1;}int PreOrderTraverse2(BiTree T, int (*visit)(TElemType e)) {//visit rootif (!(*visit)(T->data)) return 0;if (T->lchild)//visit left treeif (!PreOrderTraverse(T->lchild, visit)) return 0;if (T->rchild)//visit right treeif (!PreOrderTraverse(T->rchild, visit)) return 0;return 1;int InOrderTraverse(BiTree T, int (*visit)(TElemType e)) {if (T) {//visit left treeif (!InOrderTraverse(T->lchild, visit)) return 0;//visit rootif (!(*visit)(T->data)) return 0;//visit right treeif (!InOrderTraverse(T->rchild, visit)) return 0;}return 1;}int PostOrderTraverse(BiTree T, int (*visit)(TElemType e)) {if (T) {//visit left treeif (!PostOrderTraverse(T->lchild, visit)) return 0;//visit right treeif (!PostOrderTraverse(T->rchild, visit)) return 0;//visit rootif (!(*visit)(T->data)) return 0;}return 1;}int LevelOrderTraverse(BiTree T, int (*visit)(TElemType e)) {//defineLinkQueue queue;//initInitQueue(&queue);//root enqueueEnQueue(&queue, T);while(!QueueEmpty(queue)) {//dequeueBiTree node = DeQueue(&queue);if (node) {//visitif (!(*visit)(node->data)) return 0;//left child enqueueEnQueue(&queue, node->lchild);//right child enqueueEnQueue(&queue, node->rchild);}}DestroyQueue(&queue);return 1;}int printElem(TElemType e){printf("%d ", e);return 1;}int InitBiTree(BiTree *T){*T = NULL;return 1;}int DestroyBiTree(BiTree *T){if (*T) {//destroy left treeDestroyBiTree(&(*T)->lchild);//destroy right treeDestroyBiTree(&(*T)->rchild);//destroy rootfree(*T); *T = NULL;}return 1;}int ClearBiTree(BiTree *T){return DestroyBiTree(T);}int BiTreeEmpty(BiTree T){if (T)return 0;elsereturn 1;}int BiTreeDepth(BiTree T){if (!T)return 0;int ldepth = BiTreeDepth(T->lchild);int rdepth = BiTreeDepth(T->rchild);return (ldepth > rdepth ? ldepth : rdepth) + 1;}BiTNode *Parent(BiTree T, BiTNode *e){if (e == T) return NULL;//defineLinkQueue queue;//initInitQueue(&queue);//root enqueueEnQueue(&queue, T);BiTNode *node = NULL;while(!QueueEmpty(queue)) {//dequeuenode = DeQueue(&queue);if (node) {//compareif (e == node->lchild || e == node->rchild)break;//left child enqueueEnQueue(&queue, node->lchild);//right child enqueueEnQueue(&queue, node->rchild);}}DestroyQueue(&queue);return node;}BiTNode *LeftChild(BiTree T, BiTNode *e) {/* //defineLinkQueue queue;//initInitQueue(&queue);//root enqueueEnQueue(&queue, T);BiTNode *node = NULL;while(!QueueEmpty(queue)) {//dequeuenode = DeQueue(&queue);if (node) {//compareif (e == node)break;//left child enqueueEnQueue(&queue, node->lchild);//right child enqueueEnQueue(&queue, node->rchild);}}DestroyQueue(&queue);*/return e->lchild;}BiTNode *RightChild(BiTree T, BiTNode *e) {/* //defineLinkQueue queue;//initInitQueue(&queue);//root enqueueEnQueue(&queue, T);BiTNode *node = NULL;while(!QueueEmpty(queue)) {//dequeuenode = DeQueue(&queue);if (node) {//compareif (e == node)break;//left child enqueueEnQueue(&queue, node->lchild);//right child enqueueEnQueue(&queue, node->rchild);}}DestroyQueue(&queue);*/return e->rchild;}BiTNode *LeftSibling(BiTree T, BiTNode *e){BiTNode *parent, *lchild;if ((parent = Parent(T, e)) == NULL) return NULL;lchild = LeftChild(T, parent);if (lchild == e) return NULL;else return lchild;}BiTNode *RightSibling(BiTree T, BiTNode *e){BiTNode *parent, *rchild;if ((parent = Parent(T, e)) == NULL) return NULL;rchild = RightChild(T, parent);if (rchild == e) return NULL;else return rchild;}int InsertChild(BiTree T, BiTNode *p, int LR, BiTree C) {if (LR == 0) {C->rchild = p->lchild;p->lchild = C;} else {C->rchild = p->rchild;p->rchild = C;}return 1;}int DeleteChild(BiTree T, BiTNode *p, int LR){if (LR == 0)if (!DestroyBiTree(&p->lchild)) return 0;elseif (!DestroyBiTree(&p->rchild)) return 0;return 1;}int InitQueue(LinkQueue *Q){Q->front = Q->rear = malloc(sizeof(QueueNode));Q->front->next = NULL;}int DestroyQueue(LinkQueue *Q){QueueNode *p = Q->front, *q;do {q = p->next;free(p);p = q;} while (p!=NULL);Q->front = NULL;Q->rear = NULL;}int QueueEmpty(LinkQueue Q){return Q.front == Q.rear;}int EnQueue(LinkQueue *Q, DataType e){QueueNode *temp = malloc(sizeof(QueueNode));if (!temp) {printf("Memory is out! Cannot malloc.\n");return 0;}temp->data = e;temp->next = NULL;Q->rear->next = temp;Q->rear = temp;return 1;}DataType DeQueue(LinkQueue *Q){DataType ret = Q->front->next->data;QueueNode *p = Q->front->next;Q->front->next = Q->front->next->next;free(p);if (Q->front->next == NULL) Q->rear = Q->front;return ret;}int CountLeaf(BiTree T){if (T == NULL) return 0;if (T->lchild == NULL && T->rchild == NULL) return 1;return CountLeaf(T->lchild) + CountLeaf(T->rchild);}int CreateBiTree2(BiTree *T){int num, inorder[100], preorder[100], i = 0;printf("please input preorder:\n");while(scanf("%d", &num) != EOF) {preorder[i++] = num;}i = 0;printf("please input inorder:\n");while(scanf("%d", &num) != EOF) {inorder[i++] = num;}int index = -1;CreateBiTreeByPreInOrder(T, preorder, &index, inorder, 0, i-1, i);return 1;}int CreateBiTreeByPreInOrder(BiTree *T, int preorder[], int *idx,int inorder[], int low, int high, int length){(*idx)++;if (*idx >= length) {*T = NULL; return 1;}int i;for(i=low;i<=high;i++)if (inorder[i] == preorder[*idx]) break;if (i > high) {(*idx)--; *T = NULL; return 1;}*T = malloc(sizeof(BiTNode));if (*T == NULL)return 0;(*T)->data = preorder[*idx];if (!CreateBiTreeByPreInOrder(&(*T)->lchild, preorder, idx, inorder, low, i-1, length)) return 0;if (!CreateBiTreeByPreInOrder(&(*T)->rchild, preorder, idx, inorder, i+1, high, length)) return 0;return 1;}。