基于层次遍历的二叉树算法设计

合集下载

二叉树的遍历及常用算法

二叉树的遍历及常用算法

⼆叉树的遍历及常⽤算法⼆叉树的遍历及常⽤算法遍历的定义:按照某种次序访问⼆叉树上的所有结点,且每个节点仅被访问⼀次;遍历的重要性:当我们需要对⼀颗⼆叉树进⾏,插⼊,删除,查找等操作时,通常都需要先遍历⼆叉树,所有说:遍历是⼆叉树的基本操作;遍历思路:⼆叉树的数据结构是递归定义(每个节点都可能包含相同结构的⼦节点),所以遍历也可以使⽤递归,即结点不为空则继续递归调⽤每个节点都有三个域,数据与,左孩⼦指针和右孩⼦之指针,每次遍历只需要读取数据,递归左⼦树,递归右⼦树,这三个操作三种遍历次序:根据访问三个域的不同顺序,可以有多种不同的遍历次序,⽽通常对于⼦树的访问都按照从左往右的顺序;设: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)。

具体实现递归算法的伪代码如下:```function getHeight(node):if node is null:return 0leftHeight = getHeight(node.left)rightHeight = getHeight(node.right)return max(leftHeight, rightHeight) + 1```通过递归算法,可以方便地求出每个结点的高度。

递归算法的停止条件是当结点为空时,返回0作为高度。

在使用递归算法时,需要注意避免重复计算。

可以通过在每个结点处保存其高度,避免重复计算。

在算法的实现中,可以使用一个哈希表或者结构体来保存每个结点的高度。

除了递归算法外,还可以使用层次遍历的方法求每个结点的高度。

层次遍历是一种广度优先搜索的算法,可以按层次遍历二叉树。

在层次遍历的过程中,可以对每个结点进行标记,记录其所在的层数。

具体实现层次遍历的伪代码如下:```function getHeight(root):if root is null:return 0queue = new Queue()queue.enqueue(root)root.level = 1while queue is not empty:node = queue.dequeue()if node.left is not null:queue.enqueue(node.left)node.left.level = node.level + 1if node.right is not null:queue.enqueue(node.right)node.right.level = node.level + 1return max(node.level for node in tree)```通过层次遍历的方法,可以按层次遍历二叉树,同时记录每个结点的层数。

c语言实现二叉树的四种遍历和求深度与叶子个数

c语言实现二叉树的四种遍历和求深度与叶子个数

c语言实现二叉树的四种遍历和求深度与叶子个数二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。

在C语言中,我们可以使用指针来实现二叉树的操作。

本文将介绍四种常见的二叉树遍历方式,以及如何求解二叉树的深度和叶子节点个数。

首先,我们需要定义一个二叉树节点的结构体,包含一个数据域和两个指针域,分别指向左子节点和右子节点。

代码如下:```cstruct TreeNode {int data;struct TreeNode* left;struct TreeNode* right;};```接下来,我们可以实现二叉树的四种遍历方式:前序遍历、中序遍历、后序遍历和层序遍历。

前序遍历是指先访问根节点,然后递归地遍历左子树和右子树。

代码如下:```cvoid preorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}printf("%d ", root->data);preorderTraversal(root->left);preorderTraversal(root->right);}```中序遍历是指先递归地遍历左子树,然后访问根节点,最后递归地遍历右子树。

代码如下:```cvoid inorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}inorderTraversal(root->left);printf("%d ", root->data);inorderTraversal(root->right);}```后序遍历是指先递归地遍历左子树和右子树,最后访问根节点。

代码如下:```cvoid postorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}postorderTraversal(root->left);postorderTraversal(root->right);printf("%d ", root->data);}```层序遍历是按照树的层次逐层遍历节点。

二叉树的遍历算法实验报告

二叉树的遍历算法实验报告

二叉树的遍历算法实验报告二叉树的遍历算法实验报告引言:二叉树是计算机科学中常用的数据结构之一,它是由节点组成的层次结构,每个节点最多有两个子节点。

在实际应用中,对二叉树进行遍历是一项重要的操作,可以帮助我们理解树的结构和节点之间的关系。

本文将介绍二叉树的三种遍历算法:前序遍历、中序遍历和后序遍历,并通过实验验证其正确性和效率。

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

具体的实现可以通过递归或者使用栈来实现。

我们以递归方式实现前序遍历算法,并进行实验验证。

实验步骤:1. 创建一个二叉树,并手动构造一些节点和它们之间的关系。

2. 实现前序遍历算法的递归函数,函数的输入为根节点。

3. 在递归函数中,首先访问当前节点,然后递归调用函数遍历左子树,最后递归调用函数遍历右子树。

4. 调用前序遍历函数,输出遍历结果。

实验结果:经过实验,我们得到了正确的前序遍历结果。

这证明了前序遍历算法的正确性。

二、中序遍历中序遍历是指按照先左后根再右的顺序遍历二叉树。

同样,我们可以使用递归或者栈来实现中序遍历算法。

在本实验中,我们选择使用递归方式来实现。

实验步骤:1. 继续使用前面创建的二叉树。

2. 实现中序遍历算法的递归函数,函数的输入为根节点。

3. 在递归函数中,首先递归调用函数遍历左子树,然后访问当前节点,最后递归调用函数遍历右子树。

4. 调用中序遍历函数,输出遍历结果。

实验结果:通过实验,我们得到了正确的中序遍历结果。

这证明了中序遍历算法的正确性。

三、后序遍历后序遍历是指按照先左后右再根的顺序遍历二叉树。

同样,我们可以使用递归或者栈来实现后序遍历算法。

在本实验中,我们选择使用递归方式来实现。

实验步骤:1. 继续使用前面创建的二叉树。

2. 实现后序遍历算法的递归函数,函数的输入为根节点。

3. 在递归函数中,首先递归调用函数遍历左子树,然后递归调用函数遍历右子树,最后访问当前节点。

4. 调用后序遍历函数,输出遍历结果。

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

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

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

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

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以上是针对这个二叉树的遍历和深度的计算示例。

二叉树各个结点层次的算法

二叉树各个结点层次的算法

二叉树各个结点层次的算法在计算机科学中,二叉树的层次遍历是一种遍历二叉树的方法,其中每个节点都按照从上到下、从左到右的顺序访问。

层次遍历通常使用队列实现。

以下是使用Python实现二叉树的层次遍历的算法:pythonfrom collections import dequeclass Node:def __init__(self, data):self.left = Noneself.right = Noneself.data = datadef level_order_traversal(root):if root is None:return []result, queue = [], deque([root]) while queue:level_size = len(queue)current_level = []for _ in range(level_size):node = queue.popleft()current_level.append(node.data) if node.left:queue.append(node.left)if node.right:queue.append(node.right)result.append(current_level)return result在这个算法中,我们首先检查根节点是否为空。

如果为空,我们返回一个空列表。

然后,我们创建一个空的结果列表和一个队列,并将根节点添加到队列中。

接下来,我们进入一个循环,只要队列不为空,我们就继续循环。

在每一轮循环中,我们首先获取队列的长度,这将是当前层的节点数。

然后,我们创建一个空列表来存储当前层的节点值。

接着,我们遍历当前层的所有节点,并依次将它们从队列中弹出,然后将它们的值添加到当前层的列表中。

如果节点有左子节点或右子节点,我们将它们添加到队列中。

最后,我们将当前层的列表添加到结果列表中。

最后,当我们完成所有层的遍历时,我们返回结果列表。

数据结构实验三——二叉树基本操作及运算实验报告

数据结构实验三——二叉树基本操作及运算实验报告

《数据结构与数据库》实验报告实验题目二叉树的基本操作及运算一、需要分析问题描述:实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目,以及二叉树常用运算。

问题分析:二叉树树型结构是一类重要的非线性数据结构,对它的熟练掌握是学习数据结构的基本要求。

由于二叉树的定义本身就是一种递归定义,所以二叉树的一些基本操作也可采用递归调用的方法。

处理本问题,我觉得应该:1、建立二叉树;2、通过递归方法来遍历(先序、中序和后序)二叉树;3、通过队列应用来实现对二叉树的层次遍历;4、借用递归方法对二叉树进行一些基本操作,如:求叶子数、树的深度宽度等;5、运用广义表对二叉树进行广义表形式的打印。

算法规定:输入形式:为了方便操作,规定二叉树的元素类型都为字符型,允许各种字符类型的输入,没有元素的结点以空格输入表示,并且本实验是以先序顺序输入的。

输出形式:通过先序、中序和后序遍历的方法对树的各字符型元素进行遍历打印,再以广义表形式进行打印。

对二叉树的一些运算结果以整型输出。

程序功能:实现对二叉树的先序、中序和后序遍历,层次遍历。

计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目。

对二叉树的某个元素进行查找,对二叉树的某个结点进行删除。

测试数据:输入一:ABC□□DE□G□□F□□□(以□表示空格),查找5,删除E预测结果:先序遍历ABCDEGF中序遍历CBEGDFA后序遍历CGEFDBA层次遍历ABCDEFG广义表打印A(B(C,D(E(,G),F)))叶子数3 深度5 宽度2 非空子孙数6 度为2的数目2 度为1的数目2查找5,成功,查找的元素为E删除E后,以广义表形式打印A(B(C,D(,F)))输入二:ABD□□EH□□□CF□G□□□(以□表示空格),查找10,删除B预测结果:先序遍历ABDEHCFG中序遍历DBHEAGFC后序遍历DHEBGFCA层次遍历ABCDEFHG广义表打印A(B(D,E(H)),C(F(,G)))叶子数3 深度4 宽度3 非空子孙数7 度为2的数目2 度为1的数目3查找10,失败。

数据结构课程设计--按层次遍历二叉树

数据结构课程设计--按层次遍历二叉树

数据结构课程设计--按层次遍历二叉树学号:题目按层次遍历二叉树学院计算机科学与技术专业计算机科学与技术班级姓名指导教师2013 年 6 月 20 日11 问题描述及要求 (4)1.1问题描述 (4)1.2任务要求 ............................................................. 4 2 开发平台及所使用软件 ....................................................... 4 3 程序设计思路 (5)3.1 二叉树存储结构设计 (5)3.2 题目算法设计 (5)3.2.1 建立二叉树 (5)3.2.2 遍历二叉树 (5)3.3.3 按要求格式输出已建立的二叉树 (6)3.3 测试程序 ............................................................ 6 4 调试报告...................................................................6 5 经验和体会 ................................................................. 6 6源程序清单及运行结果 (7)6.1源程序清单 (7)6.2 运行结果 ............................................................. 9 7 参考文献..................................................................10 本科生课程设计成绩评定表 (11)2课程设计任务书学生姓名: 专业班级: 计科ZY1102班指导教师: 工作单位: 计算机科学系题目: 按层次遍历二叉树初始条件:编写按层次顺序(同一层自左至右)遍历二叉树的算法。

利用队列实现二叉树的层次遍历

利用队列实现二叉树的层次遍历

实验三利用队列实现二叉树的层次遍历实验目的(1)掌握利用二叉树的递归结构性质建立二叉链表(2)掌握循环队列的基本算法(3)掌握二叉树的遍历算法实验环境(1)Windows 2000,或WindowsXP(简体中文)(2)Visual C++ 6.0,或C++ Builder 6.0操作系统环境和编程环境(集成开发环境)任选以上所列之一。

实验内容设计一个利用队列实现二叉树层次遍历的程序。

假设二叉树结点的元素数据类型为字符型,二叉树以二叉链表存储。

利用二叉树的递归结构性质,通过读取键盘输入的如图所示二叉树的先序序列,建立其二叉链表。

实现步骤:以C++ Builder环境为例,实现步骤如下:1.新建一个Win32 Console Application程序项目。

2.在代码编辑窗口编写程序代码,含义如注释说明:#include <iostream.h>#include <conio.h>#define maxlen 10 // 定义循环队列的数组大小typedefstruct node{ char data;struct node *lp, *rp;}bt_node; // 二叉链表结点类型typedefstruct qnode{ bt_node *data[maxlen];int front, rear;}queue; // 队列数据类型void init_queue(queue &q) // 初始化队列函数{ q.front=0;q.rear=0;}int empty_queue(const queue &q) // 判队空函数{ if(q.front==q.rear) return 1;return 0;}int into_queue(queue &q, bt_node *bp) // 入队函数{ if((q.rear+1)%maxlen==q.front) return 0;q.rear=(q.rear+1)%maxlen;q.data[q.rear]=bp;return 1;}bt_node *out_queue(queue &q) // 出队函数{// if(empty_queue(q)) return NULL;q.front=(q.front+1)%maxlen;return q.data[q.front];}bt_node *create_btree() // 建立二叉链表函数{/* 读取一个元素符号;若为空元素(以特殊字符表示), 则返回空地址;否则, 申请二叉链表新结点, 将元素符号写入该结点, 递归建立其左子树和右子树, 并返回该结点地址*/char c;c=cin.get();if(c=='_')return NULL;bt_node *p = new bt_node;p->data = c;p->lp = create_btree();p->rp = create_btree();return p;}void visit(char c) // 访问元素函数{ cout<<c<<' ';}void bt_travel_width_first(bt_node *bp) // 层次遍历二叉链表函数{/* 初始化队列;若bp非空则bp入队;当队列非空, 重复下列操作:{ 出队;访问出队指针所指结点的元素;若该结点左指针非空则入队;若该结点右指针非空则入队;}*/queue treequeue;init_queue(treequeue);if(empty_queue(treequeue))into_queue(treequeue, bp) ;while(!empty_queue(treequeue)){bt_node *p = new bt_node;p = out_queue(treequeue);cout << p->data << ' ';if(p>lp!=NULL)into_queue(treequeue, p->lp) ;if(p->rp!=NULL)into_queue(treequeue, p->rp) ;}}void main(){ bt_node *Bp; // 指向二叉树根结点的指针cout<<"Input a bitree node in root-first order: \n";Bp=create_btree();cout<<"the sequence of traveling in width-first order: "<<endl;bt_travel_width_first(Bp);cout<<endl;getch();}3.保存程序项目。

二叉树遍历讲课教案ppt课件

二叉树遍历讲课教案ppt课件
I; 中序遍历序列:D,C,B,E,H,A,G, I,F,试画出二叉树,并写出该二叉树的前序 遍历序列和中序遍历序列。
资金是运动的价值,资金的价值是随 时间变 化而变 化的, 是时间 的函数 ,随时 间的推 移而增 值,其 增值的 这部分 资金就 是原有 资金的 时间价 值
6.5 线索二叉树
§ 何谓线索二叉树? § 线索链表的遍历算法 § 如何建立线索链表?
一、问题的提出
顺着某一条搜索路径巡访二叉树 中的结点,使得每个结点均被访问一 次,而且仅被访问一次。
“访问”的含义可以很是随 时间变 化而变 化的, 是时间 的函数 ,随时 间的推 移而增 值,其 增值的 这部分 资金就 是原有 资金的 时间价 值
if (T) {
visit(T->data);
// 访问结点
Preorder(T->lchild, visit); // 遍历左子树
Preorder(T->rchild, visit);// 遍历右子树 }
}
资金是运动的价值,资金的价值是随 时间变 化而变 化的, 是时间 的函数 ,随时 间的推 移而增 值,其 增值的 这部分 资金就 是原有 资金的 时间价 值
资金是运动的价值,资金的价值是随 时间变 化而变 化的, 是时间 的函数 ,随时 间的推 移而增 值,其 增值的 这部分 资金就 是原有 资金的 时间价 值
二、先左后右的遍历算法
先(根)序的遍历算法 中(根)序的遍历算法 后(根)序的遍历算法
资金是运动的价值,资金的价值是随 时间变 化而变 化的, 是时间 的函数 ,随时 间的推 移而增 值,其 增值的 这部分 资金就 是原有 资金的 时间价 值
先(根)序的遍历算法:
若二叉树为空树,则空操作;否则, (1)访问根结点; (2)先序遍历左子树; (3)先序遍历右子树。

java二叉树遍历算法

java二叉树遍历算法

java二叉树遍历算法
Java二叉树遍历是指通过沿着树的深度遍历每个节点来检索树中的所有节点的算法技术。

浅显地讲,它采用层次方式,从树根向下依次访问每个节点,直到抵达叶子节点。

它是一种非常有用的树检索算法,在不同的情况下可能用到不同的遍历策略,如前序遍历、中序遍历、后序遍历等。

通常情况下,Java二叉树遍历有三种常见的遍历模式,分别是前序遍历、中序遍历和后序遍历,每种遍历模式都有其特定的应用场景。

前序遍历的特性是对树的每个节点都按以下顺序访问:根节点、左子树节点和右子树节点,比较常用于树的克隆操作中;中序遍历是:左子树节点、根节点和右子树节点,很适合树形表示算法中的构建;后序遍历是:左子树节点、右子树节点和根节点,比较适合用于计算叶子节点的数量或者进行节点释放操作。

不论哪一种遍历模式,它们都具有共同的思想,即可以借助栈的数据结构,依次把当前的节点的右子树、节点本身和左子树依次放入栈中,以便进行下一轮的遍历,直到拿到一个空节点,就可以访问另一个节点。

因此,对于二叉树遍历,其实无论何种遍历策略,都是采用深度优先搜索作为基础,针对特定的需求采用某种访问策略,这样才能达到最佳的效果。

另外,Java 二叉树遍历 imooc 价值课程更是让构造Java树的难题变得更加容易,对于对Java 数据结构有兴趣的同学津津乐道!
本文介绍了Java二叉树遍历技术的知识背景,以及它的三种核心遍历模式,前序遍历、中序遍历和后序遍历。

作为一种有效的数据结构技术,Java二叉树遍历能方便地检索树中的所有节点,可以为树形算法的构建提供方便,受到许多技术人员的青睐,在日常的工作中也有着良好的应用前景。

输入某棵二叉树的广义表形式,建立该二叉树并按层次遍历该二叉树队列形式

输入某棵二叉树的广义表形式,建立该二叉树并按层次遍历该二叉树队列形式

掌握二叉树的二叉链表存储结构;掌握二叉树的遍历规则;利用二叉树的二叉链表存储结构实现二叉树的建树操作;利用二叉树的二叉链表存储结构实现二叉树层次遍历操作二叉树采用二叉链表结构表示。

设计并实现如下算法:输入某棵二叉树的广义表形式,建立该二叉树,并按层次遍历该二叉树----队列形式#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define STACK_MAX_SIZE 30#define QUEUE_MAX_SIZE 30typedef struct BitNode{char data;struct BitNode *lchild;struct BitNode *rchild;}BitNode,*BiTree;;typedef struct node{BitNode *data;}node,*queue;typedef struct Queue{ node *base;int front;int rear;}Queue;void InitQueue(Queue *Q){ Q->base=(queue)malloc(QUEUE_MAX_SIZE*sizeof(node)); Q->front=Q->rear=0;}int EmptyQueue(Queue *Q){ if(Q->front==Q->rear)return 1;elsereturn 0;}void EnQueue(Queue *Q,BitNode *e) { Q->base[Q->rear].data=e; Q->rear++;}BiTree DeQueue(Queue *Q){int m;m=Q->front;Q->front++;return (Q->base[m].data);}char a[50];BiTree CreatBiTree(BiTree T){BiTree p;BiTree s[STACK_MAX_SIZE];int top = -1;int flag;int i = 0;T=NULL;while(a[i]!='#'){switch(a[i]){case' ':break;case '(':top++;s[top] = p;flag = 1;break;case ')':top--;break;case ',': flag = 0; break;default: p = (BitNode *)malloc(sizeof(BitNode)); p->data = a[i];p->lchild = p->rchild = NULL; if(T==NULL){ T=p; }else{ if( flag == 1){ s[top]->lchild = p; }else { s[top]->rchild = p; } }}i++;}return T;}void LevelOrder(BiTree T) { Queue l;Queue *Q=&l;BiTree p;InitQueue(Q);if(T){EnQueue(Q,T);while(!EmptyQueue(Q)){ p=DeQueue(Q);printf("%c",p->data);if(p->lchild)EnQueue(Q,p->lchild);if(p->rchild)EnQueue(Q,p->rchild);}}}void main(){BitNode *T;printf("please input the Generalized list: \n");gets(a);T=CreatBiTree(T);printf("the order is:\n"); LevelOrder(T);getch();}。

二叉树的叶子计算方法

二叉树的叶子计算方法

二叉树的叶子计算方法引言概述:二叉树是一种常见的数据结构,它具有根节点、左子树和右子树等基本组成部分。

在二叉树中,叶子节点是指没有子节点的节点。

计算二叉树的叶子节点数量是一项重要的任务,它可以帮助我们了解二叉树的结构和特性。

本文将介绍二叉树叶子计算的方法。

正文内容:1. 递归法1.1 定义递归函数:首先,我们需要定义一个递归函数来计算二叉树的叶子节点数量。

该函数的输入参数是二叉树的根节点,返回值是叶子节点的数量。

1.2 递归终止条件:在递归函数中,我们需要定义递归的终止条件。

当递归到叶子节点时,我们将返回1,表示找到了一个叶子节点。

1.3 递归调用:在递归函数中,我们将对左子树和右子树分别调用递归函数,将它们的返回值相加,即可得到整个二叉树的叶子节点数量。

2. 迭代法2.1 使用栈数据结构:我们可以使用栈数据结构来实现二叉树的迭代计算。

首先,将根节点入栈。

2.2 迭代遍历:在迭代过程中,我们使用一个计数器来记录叶子节点的数量。

每次从栈中弹出一个节点,如果该节点是叶子节点,则将计数器加1。

然后,将该节点的左子节点和右子节点依次入栈。

2.3 迭代终止条件:当栈为空时,迭代结束,我们可以得到二叉树的叶子节点数量。

3. 层次遍历法3.1 使用队列数据结构:层次遍历是一种广度优先搜索的方法,我们可以使用队列数据结构来实现。

首先,将根节点入队。

3.2 层次遍历:在遍历过程中,我们使用一个计数器来记录叶子节点的数量。

每次从队列中出队一个节点,如果该节点是叶子节点,则将计数器加1。

然后,将该节点的左子节点和右子节点依次入队。

3.3 层次遍历终止条件:当队列为空时,遍历结束,我们可以得到二叉树的叶子节点数量。

总结:通过递归法、迭代法和层次遍历法,我们可以计算二叉树的叶子节点数量。

递归法通过定义递归函数和终止条件来实现,迭代法通过使用栈数据结构来实现,层次遍历法通过使用队列数据结构来实现。

这些方法各有优劣,可以根据实际情况选择适合的方法来计算二叉树的叶子节点数量。

层次遍历算法

层次遍历算法

层次遍历算法简介是一种二叉树遍历方式,又称为广度优先算法,它是一种从上至下、从左至右的遍历方式,最常用于树形结构进行搜索或者遍历。

可以解决一些问题,例如求二叉树的最小深度、最大深度、它的节点数、它的叶子节点数、它的某个路径等问题。

实现的方法1.使用队列实现使用队列实现是一种常用的方法。

具体步骤如下:(1)将树的根节点入队,初始化队列。

(2)当队列非空时,进行下列操作:①取出队列中的一个节点,访问该节点。

②如果该节点的左子节点不为空,则将左子节点入队。

③如果该节点的右子节点不为空,则将右子节点入队。

实现代码如下:```pythondef level_order_traversal(root):queue = []result = []if root is None:return resultqueue.append(root)while queue:node = queue.pop(0)result.append(node.val)if node.left:queue.append(node.left)if node.right:queue.append(node.right)return result```2.使用递归实现使用递归实现一般需要借助队列,并且需要知道每个节点所在的层数。

具体步骤如下:- (1)使用递归遍历左子树,直到最底层。

在遍历左子树时,需要记录当前所在的层数。

- (2)使用递归遍历右子树,直到最底层。

在遍历右子树时,需要记录当前所在的层数。

- (3)将左子树和右子树的结果合并,即可得到二叉树的层次遍历结果。

实现代码如下:```pythondef level_order_traversal(root):queue = []result = []def dfs(node, level):if not node:returnif level == len(result):result.append([])result[level].append(node.val)dfs(node.left, level+1)dfs(node.right, level+1)dfs(root, 0)return result```的应用在二叉树中的应用是十分广泛的,可以用于如下几个问题的解决:1.求最小深度二叉树的最小深度是从根节点到最近的叶子节点的距离。

二叉树的遍历教案教学设计

二叉树的遍历教案教学设计

二叉树的遍历教案教学设计教案教学设计:二叉树的遍历一、教学目标:1. 了解二叉树的遍历方式:前序遍历、中序遍历和后序遍历。

2. 能够使用递归和非递归两种方法实现二叉树的遍历。

3. 能够分析和比较不同遍历方式的时间复杂度和空间复杂度。

二、教学内容:1. 二叉树的遍历概念及分类。

2. 递归遍历算法的原理及实现。

3. 非递归遍历算法的原理及实现。

4. 比较不同遍历方式的时间复杂度和空间复杂度。

三、教学重点:1. 能够理解二叉树的遍历分类及其特点。

2. 能够使用递归和非递归两种方法实现二叉树的遍历。

四、教学难点:1. 非递归遍历算法的实现。

2. 比较不同遍历方式的时间复杂度和空间复杂度。

五、教学过程:1. 导入新知识,激发学生兴趣(5分钟)教师通过展示一棵二叉树的图片引入二叉树的遍历概念,并让学生猜测遍历的意义。

2. 介绍二叉树的遍历分类及特点(10分钟)教师介绍二叉树的遍历分类:前序遍历(根-左-右)、中序遍历(左-根-右)和后序遍历(左-右-根),并讲解每种遍历方式的特点。

3. 介绍递归遍历算法的原理及实现(15分钟)教师通过演示前序遍历的递归算法实现,介绍递归遍历的原理和递归函数的编写,让学生理解递归遍历的思路。

4. 演示递归遍历算法的应用(15分钟)教师在白板上画一棵二叉树,演示如何使用递归算法实现不同的遍历方式,并让学生跟随演示进行练习。

5. 介绍非递归遍历算法的原理及实现(15分钟)教师介绍非递归遍历算法的思路,包括使用栈数据结构进行遍历的原理及实现。

6. 演示非递归遍历算法的应用(15分钟)教师在白板上画一棵二叉树,演示如何使用非递归算法实现不同的遍历方式,并让学生跟随演示进行练习。

7. 比较不同遍历方式的时间复杂度和空间复杂度(10分钟)教师比较不同遍历方式的时间复杂度和空间复杂度,让学生了解不同的遍历方式在不同场景下的优劣。

8. 小结与作业布置(5分钟)教师对本节课进行小结,并布置作业:编写一个程序,实现二叉树的遍历,并分析所用遍历方式的时间复杂度和空间复杂度。

二叉树的四种遍历算法

二叉树的四种遍历算法

⼆叉树的四种遍历算法⼆叉树作为⼀种重要的数据结构,它的很多算法的思想在很多地⽅都⽤到了,⽐如STL算法模板,⾥⾯的优先队列、集合等等都⽤到了⼆叉树⾥⾯的思想,先从⼆叉树的遍历开始:看⼆叉树长什么样⼦:我们可以看到这颗⼆叉树⼀共有七个节点0号节点是根节点1号节点和2号节点是0号节点的⼦节点,1号节点为0号节点的左⼦节点,2号节点为0号节点的右⼦节点同时1号节点和2号节点⼜是3号节点、四号节点和五号节点、6号节点的双亲节点五号节点和6号节点没有⼦节点(⼦树),那么他们被称为‘叶⼦节点’这就是⼀些基本的概念⼆叉树的遍历⼆叉树常⽤的遍历⽅式有:前序遍历、中序遍历、后序遍历、层序遍历四种遍历⽅式,不同的遍历算法,其思想略有不同,我们来看⼀下这四种遍历⽅法主要的算法思想:1、先序遍历⼆叉树顺序:根节点 –> 左⼦树 –> 右⼦树,即先访问根节点,然后是左⼦树,最后是右⼦树。

上图中⼆叉树的前序遍历结果为:0 -> 1 -> 3 -> 4 -> 2 -> 5 -> 62、中序遍历⼆叉树顺序:左⼦树 –> 根节点 –> 右⼦树,即先访问左⼦树,然后是根节点,最后是右⼦树。

上图中⼆叉树的中序遍历结果为:3 -> 1 -> 4 -> 0 -> 5 -> 2 -> 63、后续遍历⼆叉树顺序:左⼦树 –> 右⼦树 –> 根节点,即先访问左⼦树,然后是右⼦树,最后是根节点。

上图中⼆叉树的后序遍历结果为:3 -> 4 -> 1 -> 5 -> 6 -> 2 -> 04、层序遍历⼆叉树顺序:从最顶层的节点开始,从左往右依次遍历,之后转到第⼆层,继续从左往右遍历,持续循环,直到所有节点都遍历完成上图中⼆叉树的层序遍历结果为:0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6下⾯是四种算法的伪代码:前序遍历:preOrderParse(int n) {if(tree[n] == NULL)return ; // 如果这个节点不存在,那么结束cout << tree[n].w ; // 输出当前节点内容preOrderParse(tree[n].leftChild); // 递归输出左⼦树preOrderParse(tree[n].rightChild); // 递归输出右⼦树}中序遍历inOrderParse(int n) {if(tree[n] == NULL)return ; // 如果这个节点不存在,那么结束inOrderParse(tree[n].leftChild); // 递归输出左⼦树cout << tree[n].w ; // 输出当前节点内容inOrderParse(tree[n].rightChild); // 递归输出右⼦树}pastOrderParse(int n) {if(tree[n] == NULL)return ; // 如果这个节点不存在,那么结束pastOrderParse(tree[n].leftChild); // 递归输出左⼦树pastOrderParse(tree[n].rightChild); // 递归输出右⼦树cout << tree[n].w ; // 输出当前节点内容}可以看到前三种遍历都是直接通过递归来完成,⽤递归遍历⼆叉树简答⽅便⽽且好理解,接下来层序遍历就需要动点脑筋了,我们如何将⼆叉树⼀层⼀层的遍历输出?其实在这⾥我们要借助⼀种数据结构来完成:队列。

二叉树的遍历算法

二叉树的遍历算法

二叉树的前序、后序的递归、非递归遍历算法学生姓名:贺天立指导老师:湛新霞摘要本课程设计主要解决树的前序、后序的递归、非递归遍历算法,层次序的非递归遍历算法的实现。

在课程设计中,系统开发平台为Windows 2000,程序设计设计语言采用Visual C++,程序运行平台为Windows 98/2000/XP。

用除递归算法前序,后续,中序遍历树外还通过非递归的算法遍历树。

程序通过调试运行,初步实现了设计目标,并且经过适当完善后,将可以应用在商业中解决实际问题。

关键词程序设计;C++;树的遍历;非递归遍历1 引言本课程设计主要解决树的前序、后序的递归、非递归遍历算法,层次序的非递归遍历算法的实现。

1.1课程设计的任务构造一棵树并输入数据,编写三个函数,非别是树的前序递归遍历算法、树的后序递归遍历算法、树的非递归中序遍历算法(这里的非递归以中序为例)。

在主程序中调用这三个函数进行树的遍历,观察用不同的遍历方法输出的数据的顺序和验证递归与非递归输出的数据是否一样。

1.2课程设计的性质由要求分析知,本设计主要要求解决树的前序、后序的递归、非递归遍历算法,层次序的非递归遍历算法的实现。

所以设计一个良好的前序、后序的递归、非递归遍历算法非常重要。

1.3课程设计的目的在程序设计中,可以用两种方法解决问题:一是传统的结构化程序设计方法,二是更先进的面向对象程序设计方法[1]。

利用《数据结构》课程的相关知识完成一个具有一定难度的综合设计题目,利用C语言进行程序设计。

巩固和加深对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的理解;掌握现实复杂问题的分析建模和解决方法(包括问题描述、系统分析、设计建模、代码实现、结果分析等);提高利用计算机分析解决综合性实际问题的基本能力。

树的遍历分为前序、中序和后序,可以用递归算法实现树的三种遍历。

除了递归外还可以构造栈,利用出栈和入栈来实现树的前序遍历、中序遍历和后序遍历。

二叉树的遍历课程设计

二叉树的遍历课程设计

《数据结构》课程设计报告设计题目:二叉树的遍历姓名:陈雷学号: 7专业:运算机科学与技术院系:运算机科学与技术班级: 1002指导教师:吴克力2012年 3 月1日摘要:本文主要说明如何实现二叉树的遍历。

这次二叉树的遍历基于二叉树的二叉链表存储结构。

遍历方式包括:前序遍历,中序遍历,后续遍历,层序遍历。

其中前序遍历和后续遍历采用非递归算法实现。

编程环境为VC++,除遍历操作外,还增加了求二叉树的深度,总结点数,每层结点数,和最近一路先人(LCA)问题的算法。

关键字:二叉树遍历非递归C++ LCAAbstract: This paper mainly describes how to implement binary tree traversal. The binary tree traversal is based on binary tree binary storage structure. Traversal method includes: preorder traversal,inorder traversal, postorder traversal, levelorder traversal. The former preorder traversal and postorder use of non - recursive algorithm. Programming environment is VC + +, in addition to traversal operation, also increased for solving the binary tree depth 、summary points and each layer of nodes, as well as the most recent common ancestor ( LCA ) algorithm.Keywords: binary tree traversal non-recursive C++ LCA目录一、问题描述 (4)问题描述:创建二叉树并遍历 (4)大体要求: (4)二、需求分析 (4)三、概要设计 (4)1.创建二叉树 (4)2.二叉树的非递归前序遍历示用意 (4)3.二叉树的后序非递归遍历示用意 (5)四、数据结构设计 (5)1.二叉树结点数据类型概念为: (5)2.二叉树数据类型概念为: (5)五、算法设计 (6)一、创建二叉树 (6)2、非递归前序遍历 (7)3、非递归后序遍历 (7)4、求二叉树的高度 (8)5、求二叉树每一层的结点数 (8)6、求两节点最近一路先人 (9)6、算法流程图 (10)六、程序测试与实现 (10)一、函数之间的挪用关系 (11)二、主程序 (11)3、测试数据 (12)4、测试结果 (12)七、调试分析 (14)八、碰到的问题及解决办法 (14)九、心得体会 (14)十、参考文献 (15)一、问题描述问题描述:创建二叉树并遍历大体要求:1、别离运用非递归的方式完成对二叉树的先序和后序遍历2、输出二叉树的高度3、输出每一层的结点数4、查找结点P 和结点Q的最近一路先人二、需求分析1.本程序的功能包括二叉树的成立,二叉树的递归遍历,二叉树的非递归遍历,查询二叉树的深度,查询每层的结点数,查找两个结点的最近一路先人,二叉树的打印。

二叉树的遍历

二叉树的遍历

T->rchild= CreatBiTree(); /*构造右子树*/ 扩展先序遍历序列
}
2021/2/21
return (T) ;}
A B Φ D Φ Φ C Φ 17Φ
T
T
T
ch=B
ch=Φ
Λ
T
T= Λ, Creat(T)
ch=A T
A
B creat(T L)
ΛB 返回
creat(T L)
creat(T R)
A
p=p->RChild;
}
2021/2/21
}
top
A
B
C
D
top
B
top
A
A
top
D
A
top
A
top
C
13
top
中序遍历二叉树的非递归算法:
A
void InOrder(BiTree T)
{ InitStack(&S); 相当于top=-1;
p=T;
B
C
while(p!=NULL | | !IsEmpty(S)) 相当于top==-1;
}
后序遍历二叉树的递归算法:
void PostOrder (BiTree T)
{ if(T!=NULL)
{ PostOrder (T->lchild);
PostOrder (T->rchild);
printf(T->data); }
2021/2/21
15
}
先序遍历二叉树的递归算法: void PreOder (BiTree T) { if(T! =NULL){ printf (T->data); PreOrder (T->lchild); PreOrder (T->rchild); } }
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

题目: 基于层次遍历的二叉树算法设计初始条件:理论:学习了《数据结构》课程,掌握了基本的数据结构和常用的算法;实践:计算机技术系实验室提供计算机及软件开发环境。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1、系统应具备的功能:(1)建立二叉树(2)按层次遍历二叉树2、数据结构设计;3、主要算法设计;4、编程及上机实现;5、撰写课程设计报告,包括:(1)设计题目;(2)摘要和关键字;(3)正文,包括引言、需求分析、数据结构设计、算法设计、程序实现及测试、不足之处、设计体会;(4)结束语;(5)参考文献。

时间安排:2007年7月2日-7日(第18周)7月2日查阅资料7月3日系统设计,数据结构设计,算法设计7月4日-5日编程并上机调试7月6日撰写报告7月7日验收程序,提交设计报告书。

指导教师签名: 2007年7月2日系主任(或责任教师)签名: 2007年7月2日基于层次遍历的二叉树算法设计摘要:本程序设计实现二叉树的层次遍历,该程序主要部分包括:创建二叉树,按层次遍历二叉树。

.关键字:二叉树,队列,二叉链表,数据结构.0.引言:树型结构是一类重要的非线性数据结构,其中一树和二叉树最重要。

树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构够可以用树来形象表示。

树在计算机领域中也得到了广泛应用,如在编译程序中,可以用树来表示源程序的语法结构。

二叉树是一种非线性数据结构,对它进行操作时总需要对每个数据逐一进行操作,这样就存在一个操作顺序问题,由此提出了二叉树的遍历操作问题,所谓遍历二叉树就是按某种顺序访问二叉树中某个结点一次且仅一次的过程,这里的访问可以是输出.比较.更新.查看元素内容等各种操作。

1.需求分析:1.1行输入数据构造二叉树。

1.2用队列存储二叉树结点。

1.3算法实现层次遍历。

1.4实现过程:A:初始,系统开始运行后,要先构造二叉树,先输入根结点数据信息。

B:根据提示信息输入其左子树,若没有左子树则输入“-1”。

C:根据提示信息输入其右子树,若没有右子树则输入“-1”。

D:在二叉树构造完成之后程序会自动按层次遍历二叉树,并且输出相应结点数据信息。

E:在完成上述过程之后按任意键结束程序。

2.数据结构设计:2.1树的链式存储typedef struct Bitnode /*树的链式存储*/{BitTreeElementType data;struct Bitnode *lchild; /*左孩子 */ struct Bitnode *rchild; /*右孩子*/}BTnode,*BitTree;2.2队列定义QueueElemtype data[QUEUESIZE];int front; /*队列的头指针*/int rear; /*队列的尾指针*/}queue;3.算法设计3.1主函数模块main(){“输入结点数据”;初始化二叉树;“层次遍历二叉树”;层次遍历二叉树;}3.2初始化二叉树模块Statu CreateBitTree(BitTree *T){为树指针T分配空间;输出“输入数据”;存储输入数据;if ( 出入数据==空字符){结点不存储信息;}else{结点存储输入的信息;输出“创建左子树”;CreateBitTree(&((*T)->lchild));输出“创建右子树”;CreateBitTree(&((*T)->rchild));}}3.3层次遍历二叉树模块Statu LayerTravelBitTree(BitTree T) {创建队列tq;向队列tq尾插入T;while ( 队头非空时){访问队头元素;将树左子树插入队尾;将树右子树插入队尾;}}3.4创建队列模块int CreateQueue(queue *q){对头指针和队尾指针相等;}3.5插入队列元素模块int EnQueue(queue *q, QueueElemtype c){队尾指针加1;if (队尾指针超过队列长度){输出“OVERFLOW”;退出程序;}将c存为队尾元素;}3.6删除队列元素模块Statu DeQueue(queue *q, QueueElemtype *ret){if (队头指针和队尾指针相等){返回错误;}头指针加1;将队头元素存于ret中;}3.7访问结点模块Statu VisitData(BitTreeElementType data){输出结点存储的信息;}3.7主要技术说明程序用链式存储结构和队列分别存储二叉树和二叉树的结点。

一方面采用队列存储结点是结合层次遍历二叉树和队列“先进先出”的特点综合考虑的,因为层次遍历即从上到下从左到右依次遍历二叉树结点,而队列恰好可以从上到下从左到右顺序进队然后顺序出队,符合设计的要求。

另一方面采用二叉树的链式存储结构而非顺序存储结构是因为构造二叉树需用到递归算法,采用链式存储结构容易实现。

初始化二叉树的实现:首先输入根结点,若根结点非空则将其设为树的根结点,否则返回“FALSE”;其次输入结点左子树,若非空则将其存为上一结点的左子树,否则输入右子树;若非空则将其存为上一结点的右子树,否则结束,完成二叉树初始化。

递归重复以上操作即可初始化二叉树。

本系统对用户在操作时可能进行的错误和违规操作,给出了基本的提示信息,以便用户在非法操作后得到意想不到的结果。

4.程序实现4.1库函数#include<stdio.h> /*I/O函数*/#include "conio.h"4.2定义宏#define QUEUESIZE 100 /*队列初始容量*/#define TRUE 1#define FALSE !TRUE#define Statu int#define BitTreeElementType int#define SHUJU "%d"#define END -14.3定义全局变量typedef struct Bitnode /*树的链式存储*/{BitTreeElementType data;struct Bitnode *lchild; /*左孩子 */struct Bitnode *rchild; /*右孩子*/}BTnode,*BitTree;typedef BitTree QueueElemtype;typedef struct /*定义数据结构*/{QueueElemtype data[QUEUESIZE];int front; /*队列的头指针*/int rear; /*队列的尾指针*/}queue;4.4函数原型int CreateQueue(queue *q); /*创建队列*/int EnQueue(queue *q, QueueElemtype c); /*向队尾插入元素c*/Statu DeQueue(queue *q, QueueElemtype *reb); /*队头元素出队用reb返回其值*/Statu CreateBitTree(BitTree *T); /*初始化二叉树*/Statu LayerTravelBitTree(BitTree T); /*层次遍历二叉树*/4.5主函数main(){BitTree t;printf("Input data to create bittree and '");printf( SHUJU,END);printf("' will make null tree.\n"); /*输入根结点 */CreateBitTree(&t); /*初始化二叉树*/printf("Layer order travel the tree:\n"); /*层次遍历二叉树*/ LayerTravelBitTree(t); /*层次遍历二叉树*/}4.6初始化二叉树Statu CreateBitTree(BitTree *T) /*初始化二叉树*/{BitTreeElementType inputdata;*T = (BitTree )malloc(sizeof(BTnode));printf("Enter Data:"); /*输入数据*/fflush(stdin);scanf(SHUJU,&inputdata);if ( inputdata == END)*T = NULL;return FALSE;}else{(*T)->data = inputdata; /*将输入的数据存入结点*/printf("Create left sub tree...<");CreateBitTree(&((*T)->lchild)); /*递归循环输入左子树*/ printf("Create right sub tree...<");CreateBitTree(&((*T)->rchild)); /*递归循环输入右子树*/ return TRUE;}}4.7层次遍历二叉树Statu LayerTravelBitTree(BitTree T) /*层次遍历二叉树*/ {queue tq; /*队列tq*/QueueElemtype res; /*用来返回对头元素*/CreateQueue(&tq); /*创建队列*/EnQueue(&tq,T); /*将T插入队尾*/while ( DeQueue(&tq,&res) == TRUE) /*当队头元素不空时执行while循环*/ {if (res){VisitData(res->data); /*访问队头元素*/EnQueue(&tq,res->lchild); /*将结点左孩子插入队尾*/EnQueue(&tq,res->rchild); /*将结点右孩子插入队尾*/}}}4.8创建空队列int CreateQueue(queue *q){q->front = -1;q->rear = -1;}4.9队尾插入元素(结点入队)int EnQueue(queue *q, QueueElemtype c) /*将元素c插入队尾*/{q->rear++; /*尾指针加1*/if (q->rear >= QUEUESIZE) /*若尾指针超出队列长度则提示错误*/{printf("Queue overflow!\n");exit(0);}q->data[q->rear] = c;return 1;}4.10队头元素出队Statu DeQueue(queue *q, QueueElemtype *ret) /*队头元素出队并用ret 返回其值*/{if (q->front == q->rear) /*若队列为空,则返回错误提示*/{return FALSE;}q->front++; /*头指针加1*/*ret = q->data[q->front];return TRUE;}4.11访问结点Statu VisitData(BitTreeElementType data){printf(SHUJU,data);printf("\n");return TRUE;}4.12程序运行结果主界面:结果分析:实验结果的排序完全正确。

相关文档
最新文档