数据库实现二叉树遍历

合集下载

二叉树知识点总结

二叉树知识点总结

二叉树知识点总结1. 二叉树的性质1.1 二叉树的性质一:二叉树的深度二叉树的深度是指从根节点到叶子节点的最长路径长度。

对于一个空树而言,它的深度为0;对于只有一个根节点的树而言,它的深度为1。

根据定义可知,深度为k的二叉树中,叶子节点的深度值为k。

由此可知,二叉树的深度为所有叶子节点深度的最大值。

1.2 二叉树的性质二:二叉树的高度二叉树的高度是指从根节点到叶子节点的最短路径长度。

对于一个空树而言,它的高度为0;对于只有一个根节点的树而言,它的高度为1。

由此可知,二叉树的高度总是比深度大一。

1.3 二叉树的性质三:二叉树的节点数量对于一个深度为k的二叉树而言,它最多包含2^k - 1个节点。

而对于一个拥有n个节点的二叉树而言,它的深度最多为log2(n+1)。

1.4 二叉树的性质四:满二叉树满二叉树是一种特殊类型的二叉树,它的每个节点要么是叶子节点,要么拥有两个子节点。

满二叉树的性质是:对于深度为k的满二叉树而言,它的节点数量一定是2^k - 1。

1.5 二叉树的性质五:完全二叉树完全二叉树是一种特殊类型的二叉树,它的所有叶子节点都集中在树的最低两层,并且最后一层的叶子节点从左到右依次排列。

对于一个深度为k的完全二叉树而言,它的节点数量一定在2^(k-1)和2^k之间。

2. 二叉树的遍历二叉树的遍历是指按照一定的顺序访问二叉树的所有节点。

二叉树的遍历主要包括前序遍历、中序遍历和后序遍历三种。

2.1 前序遍历(Pre-order traversal)前序遍历的顺序是:根节点 -> 左子树 -> 右子树。

对于一个二叉树而言,前序遍历的结果就是按照“根-左-右”的顺序访问所有节点。

2.2 中序遍历(In-order traversal)中序遍历的顺序是:左子树 -> 根节点 -> 右子树。

对于一个二叉树而言,中序遍历的结果就是按照“左-根-右”的顺序访问所有节点。

2.3 后序遍历(Post-order traversal)后序遍历的顺序是:左子树 -> 右子树 -> 根节点。

二叉树的遍历及常用算法

二叉树的遍历及常用算法

⼆叉树的遍历及常⽤算法⼆叉树的遍历及常⽤算法遍历的定义:按照某种次序访问⼆叉树上的所有结点,且每个节点仅被访问⼀次;遍历的重要性:当我们需要对⼀颗⼆叉树进⾏,插⼊,删除,查找等操作时,通常都需要先遍历⼆叉树,所有说:遍历是⼆叉树的基本操作;遍历思路:⼆叉树的数据结构是递归定义(每个节点都可能包含相同结构的⼦节点),所以遍历也可以使⽤递归,即结点不为空则继续递归调⽤每个节点都有三个域,数据与,左孩⼦指针和右孩⼦之指针,每次遍历只需要读取数据,递归左⼦树,递归右⼦树,这三个操作三种遍历次序:根据访问三个域的不同顺序,可以有多种不同的遍历次序,⽽通常对于⼦树的访问都按照从左往右的顺序;设:L为遍历左⼦树,D为访问根结点,R为遍历右⼦树,且L必须位于R的前⾯可以得出以下三种不同的遍历次序:先序遍历操作次序为DLR,⾸先访问根结点,其次遍历根的左⼦树,最后遍历根右⼦树,对每棵⼦树同样按这三步(先根、后左、再右)进⾏中序遍历操作次序为LDR,⾸先遍历根的左⼦树,其次访问根结点,最后遍历根右⼦树,对每棵⼦树同样按这三步(先左、后根、再右)进⾏后序遍历操作次序为LRD,⾸先遍历根的左⼦树,其次遍历根的右⼦树,最后访问根结点,对每棵⼦树同样按这三步(先左、后右、最后根)进⾏层次遍历层次遍历即按照从上到下从左到右的顺序依次遍历所有节点,实现层次遍历通常需要借助⼀个队列,将接下来要遍历的结点依次加⼊队列中;遍历的应⽤“遍历”是⼆叉树各种操作的基础,可以在遍历过程中对结点进⾏各种操作,如:对于⼀棵已知⼆叉树求⼆叉树中结点的个数求⼆叉树中叶⼦结点的个数;求⼆叉树中度为1的结点个数求⼆叉树中度为2的结点个数5求⼆叉树中⾮终端结点个数交换结点左右孩⼦判定结点所在层次等等...C语⾔实现:#include <stdio.h>//⼆叉链表数据结构定义typedef struct TNode {char data;struct TNode *lchild;struct TNode *rchild;} *BinTree, BinNode;//初始化//传⼊⼀个指针令指针指向NULLvoid initiate(BinTree *tree) {*tree = NULL;}//创建树void create(BinTree *BT) {printf("输⼊当前结点值: (0则创建空节点)\n");char data;scanf(" %c", &data);//连续输⼊整形和字符时.字符变量会接受到换⾏,所以加空格if (data == 48) {*BT = NULL;return;} else {//创建根结点//注意开辟的空间⼤⼩是结构体的⼤⼩⽽不是结构体指针⼤⼩,写错了不会⽴马产⽣问题,但是后续在其中存储数据时极有可能出现内存访问异常(飙泪....) *BT = malloc(sizeof(struct TNode));//数据域赋值(*BT)->data = data;printf("输⼊节点 %c 的左孩⼦ \n", data);create(&((*BT)->lchild));//递归创建左⼦树printf("输⼊节点 %c 的右孩⼦ \n", data);create(&((*BT)->rchild));//递归创建右⼦树}}//求双亲结点(⽗结点)BinNode *Parent(BinTree tree, char x) {if (tree == NULL)return NULL;else if ((tree->lchild != NULL && tree->lchild->data == x) || (tree->rchild != NULL && tree->rchild->data == x))return tree;else{BinNode *node1 = Parent(tree->lchild, x);BinNode *node2 = Parent(tree->rchild, x);return node1 != NULL ? node1 : node2;}}//先序遍历void PreOrder(BinTree tree) {if (tree) {//输出数据printf("%c ", tree->data);//不为空则按顺序继续递归判断该节点的两个⼦节点PreOrder(tree->lchild);PreOrder(tree->rchild);}}//中序void InOrder(BinTree tree) {if (tree) {InOrder(tree->lchild);printf("%c ", tree->data);InOrder(tree->rchild);}}//后序void PostOrder(BinTree tree) {if (tree) {PostOrder(tree->lchild);PostOrder(tree->rchild);printf("%c ", tree->data);}}//销毁结点递归free所有节点void DestroyTree(BinTree *tree) {if (*tree != NULL) {printf("free %c \n", (*tree)->data);if ((*tree)->lchild) {DestroyTree(&((*tree)->lchild));}if ((*tree)->rchild) {DestroyTree(&((*tree)->rchild));}free(*tree);*tree = NULL;}}// 查找元素为X的结点使⽤的是层次遍历BinNode *FindNode(BinTree tree, char x) {if (tree == NULL) {return NULL;}//队列BinNode *nodes[1000] = {};//队列头尾位置int front = 0, real = 0;//将根节点插⼊到队列尾nodes[real] = tree;real += 1;//若队列不为空则继续while (front != real) {//取出队列头结点输出数据BinNode *current = nodes[front];if (current->data == x) {return current;}front++;//若当前节点还有⼦(左/右)节点则将结点加⼊队列if (current->lchild != NULL) {nodes[real] = current->lchild;real++;}if (current->rchild != NULL) {nodes[real] = current->rchild;real++;}}return NULL;}//层次遍历// 查找元素为X的结点使⽤的是层次遍历void LevelOrder(BinTree tree) {if (tree == NULL) {return;}//队列BinNode *nodes[1000] = {};//队列头尾位置int front = 0, real = 0;//将根节点插⼊到队列尾nodes[real] = tree;real += 1;//若队列不为空则继续while (front != real) {//取出队列头结点输出数据BinNode *current = nodes[front];printf("%2c", current->data);front++;//若当前节点还有⼦(左/右)节点则将结点加⼊队列if (current->lchild != NULL) {nodes[real] = current->lchild;real++;}if (current->rchild != NULL) {nodes[real] = current->rchild;real++;}}}//查找x的左孩⼦BinNode *Lchild(BinTree tree, char x) {BinTree node = FindNode(tree, x);if (node != NULL) {return node->lchild;}return NULL;}//查找x的右孩⼦BinNode *Rchild(BinTree tree, char x) {BinTree node = FindNode(tree, x);if (node != NULL) {return node->rchild;}return NULL;}//求叶⼦结点数量int leafCount(BinTree *tree) {if (*tree == NULL)return 0;//若左右⼦树都为空则该节点为叶⼦,且后续不⽤接续递归了else if (!(*tree)->lchild && !(*tree)->rchild)return 1;else//若当前结点存在⼦树,则递归左右⼦树, 结果相加return leafCount(&((*tree)->lchild)) + leafCount(&((*tree)->rchild));}//求⾮叶⼦结点数量int NotLeafCount(BinTree *tree) {if (*tree == NULL)return 0;//若该结点左右⼦树均为空,则是叶⼦,且不⽤继续递归else if (!(*tree)->lchild && !(*tree)->rchild)return 0;else//若当前结点存在左右⼦树,则是⾮叶⼦结点(数量+1),在递归获取左右⼦树中的⾮叶⼦结点,结果相加 return NotLeafCount(&((*tree)->lchild)) + NotLeafCount(&((*tree)->rchild)) + 1;}//求树的⾼度(深度)int DepthCount(BinTree *tree) {if (*tree == NULL)return 0;else{//当前节点不为空则深度+1 在加上⼦树的⾼度,int lc = DepthCount(&((*tree)->lchild)) + 1;int rc = DepthCount(&((*tree)->rchild)) + 1;return lc > rc?lc:rc;// 取两⼦树深度的最⼤值 }}//删除左⼦树void RemoveLeft(BinNode *node){if (!node)return;if (node->lchild)DestroyTree(&(node->lchild));node->lchild = NULL;}//删除右⼦树void RemoveRight(BinNode *node){if (!node)return;if (node->rchild)DestroyTree(&(node->rchild));node->rchild = NULL;}int main() {BinTree tree;create(&tree);BinNode *node = Parent(tree, 'G');printf("G的⽗结点为%c\n",node->data);BinNode *node2 = Lchild(tree, 'D');printf("D的左孩⼦结点为%c\n",node2->data);BinNode *node3 = Rchild(tree, 'D');printf("D的右孩⼦结点为%c\n",node3->data);printf("先序遍历为:");PreOrder(tree);printf("\n");printf("中序遍历为:");InOrder(tree);printf("\n");printf("后序遍历为:");PostOrder(tree);printf("\n");printf("层次遍历为:");LevelOrder(tree);printf("\n");int a = leafCount(&tree);printf("叶⼦结点数为%d\n",a);int b = NotLeafCount(&tree);printf("⾮叶⼦结点数为%d\n",b);int c = DepthCount(&tree);printf("深度为%d\n",c);//查找F节点BinNode *node4 = FindNode(tree,'C');RemoveLeft(node4);printf("删除C的左孩⼦后遍历:");LevelOrder(tree);printf("\n");RemoveRight(node4);printf("删除C的右孩⼦后遍历:");LevelOrder(tree);printf("\n");//销毁树printf("销毁树 \n");DestroyTree(&tree);printf("销毁后后遍历:");LevelOrder(tree);printf("\n");printf("Hello, World!\n");return 0;}测试:测试数据为下列⼆叉树:运⾏程序复制粘贴下列内容:ABDGHECKFIJ特别感谢:iammomo。

二叉树,树,森林遍历之间的对应关系

二叉树,树,森林遍历之间的对应关系

二叉树,树,森林遍历之间的对应关系一、引言在计算机科学中,数据结构是非常重要的知识点之一。

而树这一数据结构,作为基础的数据结构之一,在软件开发中有着广泛的应用。

本文将重点探讨二叉树、树和森林遍历之间的对应关系,帮助读者更加全面地理解这些概念。

二、二叉树1. 二叉树的定义二叉树是一种特殊的树结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。

二叉树可以为空,也可以是一棵空树。

2. 二叉树的遍历在二叉树中,有三种常见的遍历方式,分别是前序遍历、中序遍历和后序遍历。

在前序遍历中,节点的访问顺序是根节点、左子树、右子树;在中序遍历中,节点的访问顺序是左子树、根节点、右子树;在后序遍历中,节点的访问顺序是左子树、右子树、根节点。

3. 二叉树的应用二叉树在计算机科学领域有着广泛的应用,例如用于构建文件系统、在数据库中存储有序数据、实现算法中的搜索和排序等。

掌握二叉树的遍历方式对于理解这些应用场景非常重要。

三、树1. 树的定义树是一种抽象数据类型,由n(n>0)个节点组成一个具有层次关系的集合。

树的特点是每个节点都有零个或多个子节点,而这些子节点又构成了一颗子树。

树中最顶层的节点称为根节点。

2. 树的遍历树的遍历方式有先根遍历、后根遍历和层次遍历。

在先根遍历中,节点的访问顺序是根节点、子树1、子树2...;在后根遍历中,节点的访问顺序是子树1、子树2...,根节点;在层次遍历中,节点的访问顺序是从上到下、从左到右依次访问每个节点。

3. 树的应用树广泛用于分层数据的表示和操作,例如在计算机网络中的路由算法、在操作系统中的文件系统、在程序设计中的树形结构等。

树的遍历方式对于处理这些应用来说至关重要。

四、森林1. 森林的定义森林是n(n>=0)棵互不相交的树的集合。

每棵树都是一颗独立的树,不存在交集。

2. 森林的遍历森林的遍历方式是树的遍历方式的超集,对森林进行遍历就是对每棵树进行遍历的集合。

3. 森林的应用森林在实际编程中经常用于解决多个独立树结构的问题,例如在数据库中对多个表进行操作、在图像处理中对多个图形进行处理等。

《二叉树模型》课件

《二叉树模型》课件

二叉树的分类
01 满二叉树
如果一个二叉树的每个节点都有两个子节点,则 该二叉树称为满二叉树。
02 完全二叉树
如果一个二叉树的最后一层是满的,且除了最后 一层外,其他各层的节点数达到最大,则该二叉 树称为完全二叉树。
03 平衡二叉树
平衡二叉树是一种特殊的完全二叉树,它的左右 子树的高度差不超过1。
二叉树的应用场景
详细描述
在n叉树模型中,每个节点可以拥有任意数 量的子节点,而不仅仅是两个。这种模型在 处理具有多个分支的数据结构时非常有用, 例如决策树和知识图谱。n叉树模型在搜索 、排序和数据压缩等领域有广泛应用。
B树模型
要点一
总结词
B树模型是一种自平衡的多路搜索树,用于数据库和文件系 统的索引。
要点二
详细描述
详细描述
二叉树的插入操作包括节点的添加和位置调整两个步骤。在添加节点时,需要找到合适 的位置将其插入到二叉树中,并保持二叉树的平衡性。位置调整是为了维护二叉树的性
质,确保每个节点的左子树和右子树的高度差不超过1。
插入操作的时间复杂度
总结词
插入操作的时间复杂度取决于具体的实现方式和数据结构。
详细描述
在平衡二叉树中,插入操作的时间复杂度为O(log n),其中n为二叉树中节点的数量。而在一般的二 叉树中,插入操作的时间复杂度可能达到O(n),因为可能需要遍历整棵树才能找到合适的位置插入新 节点。因此,选择合适的二叉树数据结构和算法对于提高插入操作的效率至关重要。
05
二叉树算法的应用
堆排序算法
平衡二叉树的性质:平衡二叉树具有以下性质:1)它的左右子树的高度差不超过1;2)它的左 子树和右子树都是平衡二叉树;3)它的左子树和右子树的节点数相差不超过1。

二叉树实验心得(优秀5篇)

二叉树实验心得(优秀5篇)

二叉树实验心得(优秀5篇)二叉树实验心得篇1二叉树实验心得在进行二叉树实验的过程中,我不仅掌握了一个重要的数据结构——二叉树,还从中体验到了深入理解一个数据结构的魅力和乐趣。

在实验开始时,我首先学习了二叉树的基本概念,如节点、左子树、右子树等。

我明白了二叉树是一种重要的数据结构,它具有层次结构,每个节点最多有两个子节点,且没有祖先节点的左或右子树中的任何一个节点。

接下来,我学习了二叉树的遍历,包括前序遍历、中序遍历和后序遍历。

通过实验,我明白了这些遍历方式的实现原理,并能够灵活地应用它们。

此外,我还学习了递归和迭代两种方法来实现这些遍历方式,这两种方法各有优点和缺点,我深入了解了它们之间的差异。

在进行实验的过程中,我遇到了一些问题,如递归方法导致的栈溢出,以及中序遍历中的栈和队列的使用。

我通过查阅资料和讨论,解决了这些问题,并从中获得了宝贵的经验。

通过这次实验,我更加深入地理解了二叉树的结构和遍历方式,并能够在实际应用中灵活使用。

我明白了数据结构的重要性,以及深入理解数据结构的过程中的乐趣。

同时,我也学会了如何解决问题,并从中获得了宝贵的经验。

总的来说,这次实验是一个非常有意义的经历,我不仅掌握了新的知识,还锻炼了自己的解决问题的能力。

我相信,这次实验将对我未来的学习和工作产生积极的影响。

二叉树实验心得篇2二叉树实验心得这次实验我们了解了二叉树的基本概念,包括二叉树、结点、左子树、右子树、祖先节点等概念。

通过实验,我们对二叉树的性质有了更深刻的理解,比如二叉树只有左子树或右子树,没有左右子树的情况,即空子树。

在实现二叉树时,我们了解了二叉树节点的定义和插入节点的多种方法,包括先插法、后插法等。

我们还学会了利用二叉树来解决实际问题,比如快速查找等问题。

在实验过程中,我们对二叉树的知识进行了深入探究,收获颇丰。

通过这次实验,我对二叉树有了更深刻的认识,明白了二叉树在计算机科学中的重要性。

同时,我对自己的编程能力也有了新的认识,发现自己可以在理解算法的基础上更好地实现它们。

二叉树先序遍历算法

二叉树先序遍历算法

二叉树先序遍历算法
二叉树先序遍历是一种树的遍历算法,先序遍历过程如下:
1. 先访问根节点;
2. 再访问左子节点;
3. 再访问右子节点;
二叉树先序遍历是一种树状数据结构的深度优先搜索(DFS)算法。

先序遍历对
树状数据结构中的每个节点仅进行一次访问,且访问的次序是从上到下,从左到右的方式。

先序遍历属于深度优先搜索,它以一定的次序访问树或图的每个节点,然后递归访问其子节点,深度优先搜索可以按一定方式去遍历有向图、二叉树等数据结构,对节点都进行一定次序的编号或标签,访问顺序是按从小到大的顺序,从而把BST全部访问一次。

二叉树先序遍历的时间复杂度为O(n),空间复杂度为O(logn),应用范围很广,常用于二叉查找树的构造或查找、求树的高度和深度、树的前中后序遍历等,其中在建立二叉查找树时,往往我们都会使用先序遍历;同时,也可用先序遍历来求二叉树的节点数,计算树的深度等。

因此,二叉树先序遍历是一种基本而又重要的数据结构遍历算法,在许多应用
场景中都可以被朂泛使用,深受各个计算机领域的热捧。

二叉树常用的三种遍历方法

二叉树常用的三种遍历方法二叉树是一种常用的数据结构,它由一个根节点和两个子节点组成,其中左子节点小于根节点,右子节点大于根节点。

遍历二叉树是对所有节点进行访问的过程,常用的三种遍历方法是前序遍历、中序遍历和后序遍历。

下面将详细介绍这三种方法的实现步骤。

一、前序遍历前序遍历是指先访问根节点,然后按照左子树、右子树的顺序依次访问每个节点。

具体实现步骤如下:1. 如果当前节点为空,则返回。

2. 访问当前节点。

3. 递归进入左子树。

4. 递归进入右子树。

代码实现:void preorderTraversal(TreeNode* root) {if (root == NULL) return;cout << root->val << " ";preorderTraversal(root->left);preorderTraversal(root->right);}二、中序遍历中序遍历是指先访问左子树,然后访问根节点,最后访问右子树。

具体实现步骤如下:1. 如果当前节点为空,则返回。

2. 递归进入左子树。

3. 访问当前节点。

4. 递归进入右子树。

代码实现:void inorderTraversal(TreeNode* root) {if (root == NULL) return;inorderTraversal(root->left);cout << root->val << " ";inorderTraversal(root->right);}三、后序遍历后序遍历是指先访问左子树,然后访问右子树,最后访问根节点。

具体实现步骤如下:1. 如果当前节点为空,则返回。

2. 递归进入左子树。

3. 递归进入右子树。

4. 访问当前节点。

代码实现:void postorderTraversal(TreeNode* root) {if (root == NULL) return;postorderTraversal(root->left);postorderTraversal(root->right);cout << root->val << " ";}总结:以上就是二叉树常用的三种遍历方法的详细介绍和实现步骤。

二叉树的广义表表示法__概述及解释说明

二叉树的广义表表示法概述及解释说明1. 引言1.1 概述二叉树是一种常见的数据结构,在计算机科学中广泛应用。

为了有效地表示和操作二叉树,人们提出了各种表示方法。

其中,二叉树的广义表表示法是一种常用且灵活的方式。

1.2 文章结构本文将首先介绍二叉树的广义表表示法的定义和特点。

然后,我们将详细讨论广义表的表示方法,并解释广义表与二叉树之间的关系。

接下来,我们将介绍如何使用广义表表示方法构建二叉树,并讨论相应的转换方法。

最后,我们将探讨在广义表表示法下如何进行遍历和操作二叉树,并提供相应的实现方法和示例场景。

1.3 目的本文的目标是全面而清晰地介绍二叉树的广义表表示法,使读者对该方法有深入理解。

通过学习本文,读者将能够掌握如何使用广义表表示法构建和操作二叉树,并能够在实际问题中应用相关技巧。

同时,本文还旨在帮助读者提高对数据结构和算法相关知识的理解水平,并培养解决实际问题时分析和抽象的能力。

这样,我们完成了“1. 引言”部分的详细撰写。

2. 二叉树的广义表表示法2.1 定义和特点二叉树是一种常用的数据结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。

二叉树的广义表表示法是一种将二叉树以字符串形式进行表示的方法。

在广义表中,以括号形式将二叉树的节点和子树进行包裹,并使用逗号分隔各个元素。

2.2 广义表的表示方法广义表由以下部分组成:- 括号:用来包裹二叉树的节点和子树。

- 节点值:表示该节点存储的数据值。

- 逗号:用于分隔各个元素。

- 空格:可选,用于提高可读性。

例如,假设有一个二叉树如下所示:```A/ \B C/ \D E```它可以表示为广义表形式为:`(A, (B, (), ()), (C, (D, (), ()), (E, (), ())))`解释上述广义表:- `(A`代表当前节点的值为A。

- `(B, (), ())`代表当前节点的左子节点为空并且右子节点为空。

- `(C, (D, (), ()), (E, (), ()))`代表当前节点的左子节点为D、右子节点为E。

二叉树的各种遍历算法及其深度算法

二叉树的各种遍历算法及其深度算法一、二叉树的遍历算法二叉树是一种常见的数据结构,遍历二叉树可以按照根节点的访问顺序将二叉树的结点访问一次且仅访问一次。

根据遍历的顺序不同,二叉树的遍历算法可以分为三种:前序遍历、中序遍历和后序遍历。

1. 前序遍历(Pre-order Traversal):首先访问根节点,然后遍历左子树,最后遍历右子树。

可以用递归或者栈来实现。

2. 中序遍历(In-order Traversal):首先遍历左子树,然后访问根节点,最后遍历右子树。

可以用递归或者栈来实现。

3. 后序遍历(Post-order Traversal):首先遍历左子树,然后遍历右子树,最后访问根节点。

可以用递归或者栈来实现。

二、二叉树的深度算法二叉树的深度,也叫做高度,指的是从根节点到叶子节点的最长路径上的节点数目。

可以使用递归或者层次遍历的方式来计算二叉树的深度。

1.递归算法:二叉树的深度等于左子树的深度和右子树的深度的较大值加一、递归的终止条件是当节点为空时,深度为0。

递归的过程中通过不断递归左子树和右子树,可以求出二叉树的深度。

2.层次遍历算法:层次遍历二叉树时,每遍历完一层节点,深度加一、使用一个队列来辅助层次遍历,先将根节点加入队列,然后依次取出队列中的节点,将其左右子节点加入队列,直到队列为空,完成层次遍历。

三、示例为了更好地理解二叉树的遍历和求深度的算法,我们以一个简单的二叉树为例进行说明。

假设该二叉树的结构如下:A/\BC/\/\DEFG其中,A、B、C、D、E、F、G分别代表二叉树的结点。

1.前序遍历:A->B->D->E->C->F->G2.中序遍历:D->B->E->A->F->C->G3.后序遍历:D->E->B->F->G->C->A4.深度:2以上是针对这个二叉树的遍历和深度的计算示例。

二叉树的遍历PPT-课件


4 、二叉树的创建算法
利用二叉树前序遍历的结果可以非常方便地生成给定的
二叉树,具体做法是:将第一个输入的结点作为二叉树的 根结点,后继输入的结点序列是二叉树左子树前序遍历的 结果,由它们生成二叉树的左子树;再接下来输入的结点 序列为二叉树右子树前序遍历的结果,应该由它们生成二 叉树的右子树;而由二叉树左子树前序遍历的结果生成二 叉树的左子树和由二叉树右子树前序遍历的结果生成二叉 树的右子树的过程均与由整棵二叉树的前序遍历结果生成 该二叉树的过程完全相同,只是所处理的对象范围不同, 于是完全可以使用递归方式加以实现。
void createbintree(bintree *t) { char ch; if ((ch=getchar())==' ') *t=NULL; else { *t=(bintnode *)malloc(sizeof(bintnode)); /*生成二叉树的根结点*/ (*t)->data=ch; createbintree(&(*t)->lchild); /*递归实现左子树的建立*/ createbintree(&(*t)->rchild); /*递归实现右子树的建立*/ }
if (s.top>-1) { t=s.data[s.top]; s.tag[s.top]=1; t=t->rchild; }
else t=NULL; }
}
7.5 二叉树其它运算的实现
由于二叉树本身的定义是递归的,因此关于二叉树的许多 问题或运算采用递归方式实现非常地简单和自然。 1、二叉树的查找locate(t,x)
(1)对一棵二叉树中序遍历时,若我们将二叉树严
格地按左子树的所有结点位于根结点的左侧,右子树的所
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1/假设现在有一个表结构如下车型起始站终点站票价依维柯 A E 200依维柯 A D 180依维柯 A B 70依维柯 B C 60依维柯 C E 90依维柯 C D 50依维柯 B E 120依维柯 A C 80沃尔沃 A E 260沃尔沃 A B 60沃尔沃 B E 180现在要写出SQL查询从起始站A到终点站E的所有可选路线及价格.查询出的结果如下:车型线路票价依维柯A-E 200依维柯A-B-E 70+120依维柯A-C-E 80+90依维柯A-B-C-E 70+60+90沃尔沃A-E 260沃尔沃A-B-E 180+60注意:只有同一种车型才可以互相转车;每条线路必须是可达的,但不能有迂回,也就是说A、B、C、D、E是依次的走,不能反过来走。

--生成测试数据create table t(车型varchar(10),起始站varchar(10),终点站varchar(10),票价int) insert into t select '依维柯','A','E',200insert into t select '依维柯','A','D',180insert into t select '依维柯','A','B',70insert into t select '依维柯','B','C',60insert into t select '依维柯','C','E',90insert into t select '依维柯','C','D',50insert into t select '依维柯','B','E',120insert into t select '依维柯','A','C',80insert into t select '沃尔沃','A','E',260insert into t select '沃尔沃','A','B',60insert into t select '沃尔沃','B','E',180go--创建用户定义函数———— @start:起始站;@end:终点站create function f_getline(@start varchar(10),@end varchar(10))returns @t table(车型varchar(10),起始站varchar(10),终点站varchar(10),线路varchar(100),票价varchar(100),level int)asbegindeclare @i intset @i = 1insert into @tselect车型,起始站,终点站,起始站+'-'+终点站,票价,@ifromtwhere起始站=@startwhile exists(select 1 from @t a,t b where a.车型=b.车型and a.终点站=b.起始站and a.终点站<b.终点站and a.终点站!=@end and a.level=@i) begininsert into @tselecta.车型,a.起始站,终点站= b.终点站,线路= a.线路+ '-' + b.终点站,票价= a.票价+ '+' + rtrim(b.票价),@i + 1from@t a,t bwherea.车型=b.车型anda.终点站=b.起始站anda.终点站<b.终点站anda.终点站!=@endanda.level = @iset @i = @i + 1enddelete @t where 终点站!= @endreturnendgo--执行查询select 车型,线路,票价from dbo.f_getline('A','E') order by 车型,level--输出结果/*车型线路票价-------- -------- ----------沃尔沃A-E 260沃尔沃A-B-E 60+180依维柯A-E 200依维柯A-B-E 70+120依维柯A-C-E 80+90依维柯A-B-C-E 70+60+90*/--删除测试环境drop function f_getlinedrop table Tgo*********************************************2/刚刚得到一个案例,在数据库中实现二叉树的遍历.我的表结构如下:ID LeftID RightID1 2 32 4 53 6 NULL4 NULL NULL5 NULL NULL6 NULL NULL如何从一个节点开始分别实现左子树和右子树的遍历?-----------------------------------------------------------------生成测试数据Create table BOM(ID int,LeftID int,RightID int)insert into BOM select 1,2 ,3insert into BOM select 2,4 ,5insert into BOM select 3,6 ,NULLinsert into BOM select 4,NULL,NULLinsert into BOM select 5,NULL,NULLinsert into BOM select 6,NULL,NULLGO--创建用户定义函数create function f_getChild(@ID int,@Type int)returns @t table(ID INT,LeftID INT,RightID INT,Level INT) asbegindeclare @i intset @i = 1insert into @tselectID,(case @Type when 1 then LeftID end),(case @Type when 2 then RightID end),@ifromBOM where ID = @IDwhile @@rowcount<>0beginset @i = @i + 1insert into @tselecta.ID,a.LeftID,a.RightID,@ifromBOM a,@t bwhere(a.ID=b.LeftID or a.ID=b.RightID) and b.Level = @i-1endreturnendgo--执行查询select ID from dbo.f_getChild(1,1) where ID != 1--输出结果/*ID245*/select ID from dbo.f_getChild(1,2) where ID != 1--输出结果/*ID----36*/--删除测试数据DROP FUNCTION f_getChildDROP TABLE BOMGO-----------------------------------------------------------------生成测试数据Create table BOM(ID int,pid int,flag int) --id自身编号,pid父编号,flag:标志是左还是右insert into BOM select 1,0,0insert into BOM select 2,1,0 --0:是左,1:是右insert into BOM select 3,1,1insert into BOM select 4,2,0insert into BOM select 5,2,1insert into BOM select 6,3,0insert into BOM select 7,6,0--创建用户定义函数create function f_getChild(@ID int,@Type int) --@type:0是左,1:是右. returns @t table(ID int,pid int,flag int,Level INT)asbegindeclare @i intset @i = 1insert into @tselect ID,pid,flag,@i from BOM where ID = @IDwhile @@rowcount<>0beginset @i = @i + 1insert into @tselect a.ID,a.pid,a.flag,@ifromBOM a,@t bwherea.pid=b.id and (a.flag=@type and @i=2 or @i>2) andb.Level = @i-1endreturnendgo--执行查询select ID from dbo.f_getChild(1,0)--输出结果/*ID----1245*/select ID from dbo.f_getChild(1,1) --输出结果/*ID----36*/--删除测试数据DROP FUNCTION f_getChild DROP TABLE BOMGO。

相关文档
最新文档