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

合集下载

二叉树的遍历及常用算法

二叉树的遍历及常用算法

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

相关文档
最新文档