创建一个二叉树并输出三种遍历结果

合集下载

二叉树的建立与基本操作

二叉树的建立与基本操作

二叉树的建立与基本操作二叉树是一种特殊的树形结构,它由节点(node)组成,每个节点最多有两个子节点。

二叉树的基本操作包括建立二叉树、遍历二叉树、查找二叉树节点、插入和删除节点等。

本文将详细介绍二叉树的建立和基本操作,并给出相应的代码示例。

一、建立二叉树建立二叉树有多种方法,包括使用数组、链表和前序、中序、后序遍历等。

下面以使用链表的方式来建立二叉树为例。

1.定义二叉树节点类首先,定义一个二叉树节点的类,包含节点值、左子节点和右子节点三个属性。

```pythonclass Node:def __init__(self, value):self.value = valueself.left = Noneself.right = None```2.建立二叉树使用递归的方法来建立二叉树,先构造根节点,然后递归地构造左子树和右子树。

```pythondef build_binary_tree(lst):if not lst: # 如果 lst 为空,则返回 Nonereturn Nonemid = len(lst) // 2 # 取 lst 的中间元素作为根节点的值root = Node(lst[mid])root.left = build_binary_tree(lst[:mid]) # 递归构造左子树root.right = build_binary_tree(lst[mid+1:]) # 递归构造右子树return root```下面是建立二叉树的示例代码:```pythonlst = [1, 2, 3, 4, 5, 6, 7]root = build_binary_tree(lst)```二、遍历二叉树遍历二叉树是指按照其中一规则访问二叉树的所有节点,常见的遍历方式有前序遍历、中序遍历和后序遍历。

1.前序遍历前序遍历是指先访问根节点,然后访问左子节点,最后访问右子节点。

```pythondef pre_order_traversal(root):if root:print(root.value) # 先访问根节点pre_order_traversal(root.left) # 递归访问左子树pre_order_traversal(root.right) # 递归访问右子树```2.中序遍历中序遍历是指先访问左子节点,然后访问根节点,最后访问右子节点。

二叉树的遍历及常用算法

二叉树的遍历及常用算法

⼆叉树的遍历及常⽤算法⼆叉树的遍历及常⽤算法遍历的定义:按照某种次序访问⼆叉树上的所有结点,且每个节点仅被访问⼀次;遍历的重要性:当我们需要对⼀颗⼆叉树进⾏,插⼊,删除,查找等操作时,通常都需要先遍历⼆叉树,所有说:遍历是⼆叉树的基本操作;遍历思路:⼆叉树的数据结构是递归定义(每个节点都可能包含相同结构的⼦节点),所以遍历也可以使⽤递归,即结点不为空则继续递归调⽤每个节点都有三个域,数据与,左孩⼦指针和右孩⼦之指针,每次遍历只需要读取数据,递归左⼦树,递归右⼦树,这三个操作三种遍历次序:根据访问三个域的不同顺序,可以有多种不同的遍历次序,⽽通常对于⼦树的访问都按照从左往右的顺序;设: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、遍历左子树2、访问根节点3、遍历右子树后序:始终执行以下步骤,1、遍历左子树2、遍历右子树3、访问根节点“始终”:为什么要说“始终”执行呢?因为二叉树的每一个子树又可以看成是一个新的二叉树,遍历步骤、方式都保持一样,所以应该“始终”执行同样的操作,我们也应该始终把它看成一棵新的二叉树。

一些技巧:1、先序遍历第一个元素一定是根节点2、中序遍历中,任何一个元素的前一个元素一定在二叉树中它的左边,比如D在G前面,则D在G左边3、后序遍历最后一个元素一定是根节点4、先、中、后意思是说访问根节点的先后顺序,而且始终从左往右,从上往下先序遍历为:ABC中序遍历为:BAC后序遍历为:BCA先序遍历为:ABDECFG中序遍历为:DBEAFCG后序遍历为:AEBFGCA前序遍历:abcdef 中序遍历:cbdaef 后序遍历:cdbfea先序遍历为:ABDGCEF 中序遍历为:DGBAECF 后序遍历为:GDBEFCA前序遍历结果为 a b d e h i c f g 中序遍历结果为 d b h e i a f c g 后序遍历结果为 d h i e b f g c a前序遍历结果为 FCADBEGHP 中序遍历结果为 ACBDFEHGP 后序遍历结果为 ABDCHPGEF前序遍历为:—+ a * b — c d / e f 中序遍历为: a + b * c — d — e / f后序遍历为: a b c d — * + e f / —前序遍历结果为ABDHEICFG中序遍历结果为HDBEIACGF后序遍历结果为HDIEBGFCA由先序序列ABCDEFGH 和中序序列CBEDAGHF 恢复二叉树: 方法: 先序序列ABCDEFGH (注:A 是根) 中序序列CBEDAGHF由左子树先序序列:BCDE 和左子树中序序列:CBED 构造A 的左子树 同理,由右子树先序序列:FGH 和右子树中序序列GHF 构造A 的右子树:1. 已知某二叉树的其前序遍历序列为1 2 4 3 5 7 6,中序遍历序列为4 2 1 5 7 3 6,求后序遍历序列(4275631)。

二叉树遍历(前序、中序、后序、层次、广度优先、深度优先遍历)

二叉树遍历(前序、中序、后序、层次、广度优先、深度优先遍历)

⼆叉树遍历(前序、中序、后序、层次、⼴度优先、深度优先遍历)⽬录转载:⼆叉树概念⼆叉树是⼀种⾮常重要的数据结构,⾮常多其他数据结构都是基于⼆叉树的基础演变⽽来的。

对于⼆叉树,有深度遍历和⼴度遍历,深度遍历有前序、中序以及后序三种遍历⽅法,⼴度遍历即我们寻常所说的层次遍历。

由于树的定义本⾝就是递归定义,因此採⽤递归的⽅法去实现树的三种遍历不仅easy理解并且代码⾮常简洁,⽽对于⼴度遍历来说,须要其他数据结构的⽀撑。

⽐⽅堆了。

所以。

对于⼀段代码来说,可读性有时候要⽐代码本⾝的效率要重要的多。

四种基本的遍历思想前序遍历:根结点 ---> 左⼦树 ---> 右⼦树中序遍历:左⼦树---> 根结点 ---> 右⼦树后序遍历:左⼦树 ---> 右⼦树 ---> 根结点层次遍历:仅仅需按层次遍历就可以⽐如。

求以下⼆叉树的各种遍历前序遍历:1 2 4 5 7 8 3 6中序遍历:4 2 7 5 8 1 3 6后序遍历:4 7 8 5 2 6 3 1层次遍历:1 2 3 4 5 6 7 8⼀、前序遍历1)依据上⽂提到的遍历思路:根结点 ---> 左⼦树 ---> 右⼦树,⾮常easy写出递归版本号:public void preOrderTraverse1(TreeNode root) {if (root != null) {System.out.print(root.val+" ");preOrderTraverse1(root.left);preOrderTraverse1(root.right);}}2)如今讨论⾮递归的版本号:依据前序遍历的顺序,优先訪问根结点。

然后在訪问左⼦树和右⼦树。

所以。

对于随意结点node。

第⼀部分即直接訪问之,之后在推断左⼦树是否为空,不为空时即反复上⾯的步骤,直到其为空。

若为空。

则须要訪问右⼦树。

注意。

在訪问过左孩⼦之后。

二叉树遍历(前中后序遍历,三种方式)

二叉树遍历(前中后序遍历,三种方式)

⼆叉树遍历(前中后序遍历,三种⽅式)⽬录刷题中碰到⼆叉树的遍历,就查找了⼆叉树遍历的⼏种思路,在此做个总结。

对应的LeetCode题⽬如下:,,,接下来以前序遍历来说明三种解法的思想,后⾯中序和后续直接给出代码。

⾸先定义⼆叉树的数据结构如下://Definition for a binary tree node.struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}};前序遍历,顺序是“根-左-右”。

使⽤递归实现:递归的思想很简单就是我们每次访问根节点后就递归访问其左节点,左节点访问结束后再递归的访问右节点。

代码如下:class Solution {public:vector<int> preorderTraversal(TreeNode* root) {if(root == NULL) return {};vector<int> res;helper(root,res);return res;}void helper(TreeNode *root, vector<int> &res){res.push_back(root->val);if(root->left) helper(root->left, res);if(root->right) helper(root->right, res);}};使⽤辅助栈迭代实现:算法为:先把根节点push到辅助栈中,然后循环检测栈是否为空,若不空,则取出栈顶元素,保存值到vector中,之后由于需要想访问左⼦节点,所以我们在将根节点的⼦节点⼊栈时要先经右节点⼊栈,再将左节点⼊栈,这样出栈时就会先判断左⼦节点。

代码如下:class Solution {public:vector<int> preorderTraversal(TreeNode* root) {if(root == NULL) return {};vector<int> res;stack<TreeNode*> st;st.push(root);while(!st.empty()){//将根节点出栈放⼊结果集中TreeNode *t = st.top();st.pop();res.push_back(t->val);//先⼊栈右节点,后左节点if(t->right) st.push(t->right);if(t->left) st.push(t->left);}return res;}};Morris Traversal⽅法具体的详细解释可以参考如下链接:这种解法可以实现O(N)的时间复杂度和O(1)的空间复杂度。

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

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

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

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

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

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

具体实现步骤如下: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 << " ";}总结:以上就是二叉树常用的三种遍历方法的详细介绍和实现步骤。

C语言实现创建二叉树,先序遍历、中序遍历、后序遍历输出

C语言实现创建二叉树,先序遍历、中序遍历、后序遍历输出

C语⾔实现创建⼆叉树,先序遍历、中序遍历、后序遍历输出# include <stdio.h># include <stdlib.h># include <string.h># include <iostream># define OK 0;# define ERROR -1;typedef int TElemType;typedef char DataType;typedef int Status;typedef struct BiNode {DataType data;//存⾃定义类型的值struct BiNode *lchild, *rchild;//左右⼩孩指针}BiNode,*BiTree;void CreatBiNode(BiNode **Node)//此处应注意传递的参数(⼆重指针){char data;scanf_s("%c", &data);*Node = (BiTree)malloc(sizeof(BiNode));if (data == '#'){*Node = NULL;}else if ((data != '#') && (*Node)){(*Node)->data = data;(*Node)->lchild = NULL;(*Node)->rchild = NULL;CreatBiNode(&(*Node)->lchild);CreatBiNode(&(*Node)->rchild);}}Status PreOrderTraverse(BiTree T) {if (T == NULL) {return OK;}else {printf("%c", T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}}Status InOrderTraverse(BiTree T) {if (T == NULL) {return OK;}else {InOrderTraverse(T->lchild);printf("%c", T->data);InOrderTraverse(T->rchild);}}Status PostOrderTraverse(BiTree T) {if (T == NULL) {return OK;}else {PostOrderTraverse(T->lchild);PostOrderTraverse(T->rchild);printf("%c", T->data);}}int main(){printf("先序输⼊⼆叉树(空结点⽤'#'表⽰):");BiTree T=NULL;CreatBiNode(&T);printf("先序遍历⼆叉树:");PreOrderTraverse(T);printf("\n中序遍历⼆叉树:");InOrderTraverse(T);printf("\n后序遍历⼆叉树:");PostOrderTraverse(T);system("pause");return 0;}解决思想:⼩⽣⽤的是递归创建⼆叉树,递归遍历⼆叉树,因为使⽤递归会⽐较简洁。

数据结构课程设计报告-最短路径算法-二叉树的三种遍历

数据结构课程设计报告-最短路径算法-二叉树的三种遍历

数据结构课程设计报告班级:计算机科学与技术132班姓名:赖恒财指导教师:董跃华成绩:32信息工程学院2015 年7月8日目录图的最短路径算法实现1. 需求分析 (1)1.1 程序设计内容 (1)1.2 设计要求 (1)2.概要设计 (2)3.详细设计 (2)3.1 数据类型的定义 (2)3.2 功能模块的设计 (2)3.3 主程序流程 (9)4.调试分析 (10)4.1 问题回顾和分析 (10)4.2.经验和体会 (11)5.测试结果 (12)二叉树的遍历1.设计目的 (13)2.需求分析 (14)2.1课程设计的内容和要求 (14)2.2选题的意义及背景 (14)3.概要设计 (14)3.1设计思想 (14)3.2程序数据类型 (16)3.3程序模块分析 (16)3.3.1置空栈 (16)3.3.2入栈 (17)3.3.3出栈 (17)3.3.4取栈顶操作 (17)3.3.5判空栈 (17)3.4函数关系: (18)4.详细设计 (18)4.1二叉树算法程序截图和结果 (18)5.程序测试结果及问题分析 (19)6.总结 (20)参考文献 (21)附录1 (22)附录2 (26)图的最短路径算法实现----基于floyd最短路径算法1.需求分析设计校园平面图,所含景点不少于8个。

以图中顶点表示学校内各景点,存放景点的名称、景点介绍信息等;以边表示路径,存放路径长度信息。

要求将这些信息保存在文件graph.txt中,系统执行时所处理的数据要对此文件分别进行读写操作。

1.1程序设计内容1.从文件graph.txt中读取相应数据, 创建一个图,使用邻接矩阵表示图;2.景点信息查询:为来访客人提供校园任意景点相关信息的介绍;3.问路查询:为来访客人提供校园任意两个景点之间的一条最短路径。

1.2 设计要求(1) 程序要具在一定的健壮性,即当输入数据非法时,程序也能适当地做出反应。

(2) 程序要添加适当的注释,程序的书写要采用缩进格式。

二叉树遍历实验报告

二叉树遍历实验报告

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

二叉树的遍历是指按照一定的规则访问二叉树中的所有节点。

本实验旨在通过实际操作,探索二叉树的三种遍历方式:前序遍历、中序遍历和后序遍历,并分析它们的应用场景和性能特点。

二、实验方法1. 实验环境本实验使用Python编程语言进行实现,并在Jupyter Notebook中运行代码。

2. 实验步骤(1)定义二叉树节点类首先,我们定义一个二叉树节点类,该类包含节点值、左子节点和右子节点三个属性。

(2)构建二叉树在主函数中,我们手动构建一个二叉树,包含多个节点,并将其保存为根节点。

(3)实现三种遍历方式通过递归的方式,实现二叉树的前序遍历、中序遍历和后序遍历。

具体实现过程如下:- 前序遍历:先访问根节点,然后递归遍历左子树,最后递归遍历右子树。

- 中序遍历:先递归遍历左子树,然后访问根节点,最后递归遍历右子树。

- 后序遍历:先递归遍历左子树,然后递归遍历右子树,最后访问根节点。

(4)测试遍历结果在主函数中,我们调用实现的三种遍历方式,对构建的二叉树进行遍历,并输出结果。

三、实验结果与分析经过实验,我们得到了二叉树的前序遍历、中序遍历和后序遍历的结果。

以下是我们的实验结果及分析:1. 前序遍历结果前序遍历结果为:A - B - D - E - C - F - G前序遍历的应用场景包括:复制整个二叉树、计算二叉树的深度和宽度等。

前序遍历的时间复杂度为O(n),其中n为二叉树的节点数。

2. 中序遍历结果中序遍历结果为:D - B - E - A - F - C - G中序遍历的应用场景包括:二叉搜索树的中序遍历可以得到有序的节点序列。

中序遍历的时间复杂度为O(n),其中n为二叉树的节点数。

3. 后序遍历结果后序遍历结果为:D - E - B - F - G - C - A后序遍历的应用场景包括:计算二叉树的高度、判断二叉树是否对称等。

二叉树的建立和遍历的实验报告

二叉树的建立和遍历的实验报告

竭诚为您提供优质文档/双击可除二叉树的建立和遍历的实验报告篇一:二叉树遍历实验报告数据结构实验报告报告题目:二叉树的基本操作学生班级:学生姓名:学号:一.实验目的1、基本要求:深刻理解二叉树性质和各种存储结构的特点及适用范围;掌握用指针类型描述、访问和处理二叉树的运算;熟练掌握二叉树的遍历算法;。

2、较高要求:在遍历算法的基础上设计二叉树更复杂操作算法;认识哈夫曼树、哈夫曼编码的作用和意义;掌握树与森林的存储与便利。

二.实验学时:课内实验学时:3学时课外实验学时:6学时三.实验题目1.以二叉链表为存储结构,实现二叉树的创建、遍历(实验类型:验证型)1)问题描述:在主程序中设计一个简单的菜单,分别调用相应的函数功能:1…建立树2…前序遍历树3…中序遍历树4…后序遍历树5…求二叉树的高度6…求二叉树的叶子节点7…非递归中序遍历树0…结束2)实验要求:在程序中定义下述函数,并实现要求的函数功能:createbinTree(binTreestructnode*lchild,*rchild;}binTnode;元素类型:intcreatebinTree(binTreevoidpreorder(binTreevoidInorder(binTreevoidpostorder(binTreevoidInordern(binTreeintleaf(bi nTreeintpostTreeDepth(binTree2、编写算法实现二叉树的非递归中序遍历和求二叉树高度。

1)问题描述:实现二叉树的非递归中序遍历和求二叉树高度2)实验要求:以二叉链表作为存储结构3)实现过程:1、实现非递归中序遍历代码:voidcbiTree::Inordern(binTreeinttop=0;p=T;do{while(p!=nuLL){stack[top]=p;;top=top+1;p=p->lchild;};if(top>0){top=top-1;p=stack[top];printf("%3c",p->data);p=p->rchild;}}while(p!=nuLL||top!=0);}2、求二叉树高度:intcbiTree::postTreeDepth(binTreeif(T!=nuLL){l=postTreeDepth(T->lchild);r=postTreeDepth(T->rchil d);max=l>r?l:r;return(max+1);}elsereturn(0);}实验步骤:1)新建一个基于consoleApplication的工程,工程名称biTreeTest;2)新建一个类cbiTree二叉树类。

二叉树的遍历代码

二叉树的遍历代码

二叉树的遍历代码二叉树是一种非常常见的数据结构,它由根节点、左子树和右子树组成,可以用于实现各种算法和应用。

在使用二叉树时,我们常常需要进行遍历来获取树中的节点信息。

下面,我们将详细介绍二叉树的遍历方法及其代码实现。

二叉树的遍历方法分为三种:前序遍历、中序遍历和后序遍历。

它们的不同之处在于遍历节点的顺序不同。

我们分别来介绍一下这三种遍历方法。

1.前序遍历前序遍历的顺序是:先访问根节点,然后递归访问左子树和右子树。

实现前序遍历的代码如下:```pythondef preorder_traversal(node):if node:print(node.data)preorder_traversal(node.left)preorder_traversal(node.right)```在代码中,我们首先输出根节点的值,然后分别递归访问左子树和右子树,直到遍历完整个树。

2.中序遍历中序遍历的顺序是:先递归访问左子树,然后访问根节点,最后递归访问右子树。

实现中序遍历的代码如下:```pythondef inorder_traversal(node):if node:inorder_traversal(node.left)print(node.data)inorder_traversal(node.right)```在代码中,我们先递归访问左子树,然后输出根节点的值,最后递归访问右子树。

3.后序遍历后序遍历的顺序是:先递归访问左子树和右子树,然后访问根节点。

实现后序遍历的代码如下:```pythondef postorder_traversal(node):if node:postorder_traversal(node.left)postorder_traversal(node.right)print(node.data)```在代码中,我们先递归访问左子树和右子树,然后输出根节点的值。

通过前序遍历、中序遍历和后序遍历,我们可以获取二叉树中每个节点的值。

c++实现树(二叉树)的建立和遍历算法(一)(前序,中序,后序)

c++实现树(二叉树)的建立和遍历算法(一)(前序,中序,后序)

c++实现树(⼆叉树)的建⽴和遍历算法(⼀)(前序,中序,后序)最近学习树的概念,有关⼆叉树的实现算法记录下来。

不过学习之前要了解的预备知识:树的概念;⼆叉树的存储结构;⼆叉树的遍历⽅法。

⼆叉树的存储结构主要了解⼆叉链表结构,也就是⼀个数据域,两个指针域,(分别为指向左右孩⼦的指针),从下⾯程序1,⼆叉树的存储结构可以看出。

⼆叉树的遍历⽅法:主要有前序遍历,中序遍历,后序遍历,层序遍历。

(层序遍历下⼀篇再讲,本篇主要讲的递归法)下篇主要是,之后会有c++模板实现和。

如这样⼀个⼆叉树:它的前序遍历顺序为:ABDGHCEIF(规则是先是根结点,再前序遍历左⼦树,再前序遍历右⼦树)它的中序遍历顺序为:GDHBAEICF(规则是先中序遍历左⼦树,再是根结点,再是中序遍历右⼦树)它的后序遍历顺序为:GHDBIEFCA(规则是先后序遍历左⼦树,再是后序遍历右⼦树,再是根结点)如果不懂的话,可以参看有关数据结构的书籍。

1,⼆叉树的存储结构(⼆叉链表)//⼆叉树的⼆叉链表结构,也就是⼆叉树的存储结构,1个数据域,2个指针域(分别指向左右孩⼦)typedef struct BiTNode{ElemType data;struct BiTNode *lchild, *rchild;}BiTNode, *BiTree;2,⾸先要建⽴⼀个⼆叉树,建⽴⼆叉树必须要了解⼆叉树的遍历⽅法。

//⼆叉树的建⽴,按前序遍历的⽅式建⽴⼆叉树,当然也可以以中序或后序的⽅式建⽴⼆叉树void CreateBiTree(BiTree *T){ElemType ch;cin >> ch;if (ch == '#')*T = NULL; //保证是叶结点else{*T = (BiTree)malloc(sizeof(BiTNode));//if (!*T)//exit(OVERFLOW); //内存分配失败则退出。

二叉树的遍历有三种方式

二叉树的遍历有三种方式

二叉树的遍历有三种方式,如下:(1)前序遍历(DLR),首先访问根结点,然后遍历左子树,最后遍历右子树。

简记根-左-右。

(2)中序遍历(LDR),首先遍历左子树,然后访问根结点,最后遍历右子树。

简记左-根-右。

(3)后序遍历(LRD),首先遍历左子树,然后遍历右子树,最后访问根结点。

简记左-右-根。

例1:如上图所示的二叉树,若按前序遍历,则其输出序列为。

若按中序遍历,则其输出序列为。

若按后序遍历,则其输出序列为。

前序:根A,A的左子树B,B的左子树没有,看右子树,为D,所以A-B-D。

再来看A的右子树,根C,左子树E,E的左子树F,E的右子树G,G的左子树为H,没有了结束。

连起来为C-E-F-G-H,最后结果为ABDCEFGH中序:先访问根的左子树,B没有左子树,其有右子树D,D无左子树,下面访问树的根A,连起来是BDA。

再访问根的右子树,C的左子树的左子树是F,F的根E,E的右子树有左子树是H,再从H出发找到G,到此C的左子树结束,找到根C,无右子树,结束。

连起来是FEHGC, 中序结果连起来是BDAFEHGC 后序:B无左子树,有右子树D,再到根B。

再看右子树,最下面的左子树是F,其根的右子树的左子树是H,再到H的根G,再到G的根E,E的根C无右子树了,直接到C,这时再和B找它们其有的根A,所以连起来是DBFHGECA例2:有下列二叉树,对此二叉树前序遍历的结果为()。

A)ACBEDGFH B)ABDGCEHFC)HGFEDCBA D)ABCDEFGH解析:先根A,左子树先根B,B无左子树,其右子树,先根D,在左子树G,连起来是ABDG。

A的右子树,先根C,C左子树E,E无左子树,有右子树为H,C的右子树只有F,连起来是CEHF。

整个连起来是B答案ABDGCEHF。

例3:已知二叉树后序遍历是DABEC,中序遍历序列是DEBAC,它的前序遍历序列是( ) 。

A)CEDBA B)ACBED C)DECAB D)DEABC解析:由后序遍历可知,C为根结点,由中序遍历可知,C左边的是左子树含DEBA,C右边无结点,知根结点无右子树。

二叉树的建立和遍历实验报告

二叉树的建立和遍历实验报告

二叉树的建立和遍历实验报告一、引言(100字)二叉树是一种常见的数据结构,它由根节点、左子树和右子树组成,具有递归性质。

本次实验的目的是了解二叉树的建立过程和遍历算法,以及熟悉二叉树的相关操作。

本实验采用C语言进行编写。

二、实验内容(200字)1.二叉树的建立:通过输入节点的值,逐个建立二叉树的节点,并通过指针连接起来。

2.二叉树的遍历:实现二叉树的三种常用遍历算法,即前序遍历、中序遍历和后序遍历。

三、实验过程(400字)1.二叉树的建立:首先,定义二叉树的节点结构,包含节点值和指向左右子树的指针;然后,通过递归的方式,依次输入节点的值,创建二叉树节点,建立好节点之间的连接。

2.二叉树的前序遍历:定义一个函数,实现前序遍历的递归算法,先输出当前节点的值,再递归遍历左子树和右子树。

3.二叉树的中序遍历:同样,定义一个函数,实现中序遍历的递归算法,先递归遍历左子树,再输出当前节点的值,最后递归遍历右子树。

4.二叉树的后序遍历:同样,定义一个函数,实现后序遍历的递归算法,先递归遍历左子树和右子树,再输出当前节点的值。

四、实验结果(300字)通过实验,我成功建立了一个二叉树,并实现了三种遍历算法。

对于建立二叉树来说,只要按照递归的思路,先输入根节点的值,再分别输入左子树和右子树的值,即可依次建立好节点之间的连接。

建立好二叉树后,即可进行遍历操作。

在进行遍历算法的实现时,我首先定义了一个函数来进行递归遍历操作。

在每一次递归调用中,我首先判断当前节点是否为空,若为空则直接返回;若不为空,则按照特定的顺序进行遍历操作。

在前序遍历中,我先输出当前节点的值,再递归遍历左子树和右子树;在中序遍历中,我先递归遍历左子树,再输出当前节点的值,最后递归遍历右子树;在后序遍历中,我先递归遍历左子树和右子树,再输出当前节点的值。

通过运行程序,我成功进行了二叉树的建立和遍历,并得到了正确的结果。

可以看到,通过不同的遍历顺序,可以获得不同的遍历结果,这也是二叉树遍历算法的特性所在。

创建二叉树的三种算法

创建二叉树的三种算法

创建二叉树的三种算法1.递归算法递归算法是最直观也是最常用的创建二叉树的方法之一、递归算法通过递归地创建左子树和右子树来构建完整的二叉树。

具体步骤如下:-创建一个二叉树结构的定义,包含一个存储数据的变量和左右子节点。

-如果当前节点为空,直接将新节点插入当前位置。

-如果新节点的值小于当前节点的值,递归地将新节点插入当前节点的左子树。

-如果新节点的值大于等于当前节点的值,递归地将新节点插入当前节点的右子树。

递归算法的示例代码如下所示:```pythonclass TreeNode:def __init__(self, val):self.val = valself.left = Noneself.right = Nonedef insert(root, val):if root is None:return TreeNode(val)if val < root.val:root.left = insert(root.left, val)elif val >= root.val:root.right = insert(root.right, val)return root```2.先序遍历算法先序遍历算法通过遍历给定的节点集合,按照先序的顺序将节点逐个插入到二叉树中。

这种算法可以使用栈来实现。

具体步骤如下:-创建一个空栈,同时创建一个新节点的拷贝作为当前节点。

-依次遍历给定的节点集合,如果新节点的值小于当前节点的值,将当前节点的左子节点指向新节点,并将新节点入栈,并将新节点移动到当前节点的左子节点。

-如果新节点的值大于等于当前节点的值,重复上述过程,直到找到一个合适的位置并插入新节点。

-当遍历完所有节点后,返回二叉树的根节点。

先序遍历算法的示例代码如下所示:```pythonclass TreeNode:def __init__(self, val): self.val = valself.left = Noneself.right = Nonedef insert(root, val): if root is None:return TreeNode(val) stack = []cur = rootwhile True:if val < cur.val:if not cur.left:cur.left = TreeNode(val) breakelse:cur = cur.leftelse:if not cur.right:cur.right = TreeNode(val)breakelse:cur = cur.rightreturn root```3.层次遍历算法层次遍历算法通过逐层遍历给定的节点集合,按照从上到下、从左到右的顺序将节点逐个插入到二叉树中。

二叉树的创建与遍历的实验总结

二叉树的创建与遍历的实验总结

二叉树的创建与遍历的实验总结引言二叉树是一种重要的数据结构,在计算机科学中有着广泛的应用。

了解二叉树的创建和遍历方法对于数据结构的学习和算法的理解至关重要。

本文将对二叉树的创建和遍历进行实验,并总结相应的经验和思考。

二叉树的定义在开始实验之前,我们首先需要了解二叉树的定义和基本概念。

二叉树是一种每个节点最多拥有两个子节点的树形结构。

每个节点包含一个值和指向其左右子节点的指针。

根据节点的位置,可以将二叉树分为左子树和右子树。

创建二叉树二叉树的创建可以采用多种方法,包括手动创建和通过编程实现。

在实验中,我们主要关注通过编程方式实现二叉树的创建。

1. 递归方法递归是一种常用的创建二叉树的方法。

通过递归,我们可以从根节点开始,逐层创建左子树和右子树。

具体步骤如下:1.创建一个空节点作为根节点。

2.递归地创建左子树。

3.递归地创建右子树。

递归方法的代码实现如下所示:class TreeNode:def __init__(self, value):self.value = valueself.left = Noneself.right = Nonedef create_binary_tree(values):if not values:return None# 使用队列辅助创建二叉树queue = []root = TreeNode(values[0])queue.append(root)for i in range(1, len(values)):node = TreeNode(values[i])# 当前节点的左子节点为空,则将新节点作为左子节点if not queue[0].left:queue[0].left = node# 当前节点的右子节点为空,则将新节点作为右子节点elif not queue[0].right:queue[0].right = node# 当前节点的左右子节点已经齐全,可以从队列中删除该节点queue.pop(0)# 将新节点添加到队列中,下一次循环时可以使用该节点queue.append(node)return root2. 非递归方法除了递归方法,我们还可以使用非递归方法创建二叉树。

二叉树的四种遍历算法

二叉树的四种遍历算法

⼆叉树的四种遍历算法⼆叉树作为⼀种重要的数据结构,它的很多算法的思想在很多地⽅都⽤到了,⽐如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 ; // 输出当前节点内容}可以看到前三种遍历都是直接通过递归来完成,⽤递归遍历⼆叉树简答⽅便⽽且好理解,接下来层序遍历就需要动点脑筋了,我们如何将⼆叉树⼀层⼀层的遍历输出?其实在这⾥我们要借助⼀种数据结构来完成:队列。

二叉树的三种遍历方式

二叉树的三种遍历方式

⼆叉树的三种遍历⽅式⼀、⼆叉树的定义⼆叉树(Binary Tree)的递归定义:⼆叉树要么为空,要么由根节点(root)、左⼦树(left subtree)和右⼦树(right subtree)组成,⽽左⼦书和右⼦树分别是⼀颗⼆叉树。

注意,在计算机中,树⼀般是"倒置"的,即根在上,叶⼦在下。

⼆、⼆叉树的层次遍历三种遍历⽅式:先序遍历、中序遍历、后序遍历(根据根节点的顺序)PreOrder(T) = T的根节点 + PreOrder(T的左⼦树) + PreOrder(T的右⼦树)InOrder(T) = InOrder(T的左⼦树) + T的根节点 + InOrder(T的右⼦树)PostOrder(T) = PostOrder(左⼦树) + PostOrder(右⼦树)其中加号表⽰字符串连接这三种遍历都是递归遍历或者说深度优先遍历 (DFS,Depth-First-Search)三、已知两种遍历⽅式,推出另⼀种遍历⽅式先序+中序---->后序后序+中序---->先序因为后序或先序可以直接得到根节点,然后只要在中序遍历中找到,就知道左右⼦树的中序和后序遍历,递归下去就可以构造出⼆叉树了。

四、样例(1) 题意:给⼀颗点带权(各权值都不相同,都是⼩于10000的整数)的⼆叉树的中序和后序遍历,找⼀个叶⼦节点使它到根的路径上的权应尽量少。

(2) 代码实现:1 #include<stdio.h>2 #include<iostream>3 #include<algorithm>4 #include<cstring>5 #include<string>6 #include<sstream>7using namespace std;89const int INF = 0x3f3f3f3f;10//因为各节点的权值各不相同且都只是整数,直接⽤权值作为节点编号11const int maxn = 10000 + 10;12int in_order[maxn], post_order[maxn], lch[maxn], rch[maxn];13int n;14int best, best_sum;1516//按⾏读取数据,并存到数组中17bool read_list(int *a)18{19string line;20if (!getline(cin, line)) return false;21 stringstream ss(line);22 n = 0;23int x;24while (ss >> x) a[n++] = x;25return n > 0;26}2728//把in_order[L1,R1]和post_order[L2,R2]建成⼀棵⼆叉树,返回树根29int build(int L1, int R1, int L2, int R2)30{31if (L2 > R2) return0; //空树32int root = post_order[R2];33int pos = L1;34while (in_order[pos] != root) pos++;35int cnt = pos - L1;36 lch[root] = build(L1, pos - 1, L2, L2 + cnt - 1);37 rch[root] = build(pos + 1, R1, L2 + cnt, R2 - 1);38return root;39}4041//从根节点出发,中序遍历,查找最⼩值42void dfs(int u, int sum)43{44 sum += u;4546//到达叶⼦节点,循环终⽌47if (!lch[u] && !rch[u])48 {49if (sum < best_sum)50 {51 best = u;52 best_sum = sum;53 }54return;55 }5657//加了个剪枝:如果当前的和⼤于当前的最⼩和,就不必从这条路继续搜58if (lch[u] && sum < best_sum) dfs(lch[u], sum);59if (rch[u] && sum < best_sum) dfs(rch[u], sum);60}6162int main()63{64while (read_list(in_order))65 {66 read_list(post_order);67 build(0, n - 1, 0, n - 1);6869 best_sum = INF;70 dfs(post_order[n - 1], 0);71 cout << best << endl;72 }73return0;74 }。

三种遍历方法

三种遍历方法

三种遍历方法一、前序遍历前序遍历是二叉树遍历的一种方法,也是最常见的遍历方式之一。

在前序遍历中,首先访问根节点,然后递归地遍历左子树,最后递归地遍历右子树。

前序遍历的应用非常广泛,例如在二叉树的构建和重建、树的深度优先搜索等问题中都会用到前序遍历。

在进行前序遍历时,可以采用递归或者非递归的方式。

1. 递归实现前序遍历:递归实现前序遍历非常简单,具体步骤如下:- 首先判断当前节点是否为空,若为空则返回;- 访问当前节点;- 递归遍历左子树;- 递归遍历右子树。

2. 非递归实现前序遍历:非递归实现前序遍历需要借助栈来实现,具体步骤如下:- 将根节点入栈;- 循环执行以下步骤,直到栈为空:- 弹出栈顶节点,并访问该节点;- 若该节点的右子节点不为空,则将右子节点入栈;- 若该节点的左子节点不为空,则将左子节点入栈。

二、中序遍历中序遍历是二叉树遍历的另一种方法,同样也是一种常用的遍历方式。

在中序遍历中,首先递归地遍历左子树,然后访问根节点,最后递归地遍历右子树。

中序遍历的应用也非常广泛,例如在二叉搜索树的操作中,中序遍历可以按照升序输出所有节点的值。

1. 递归实现中序遍历:递归实现中序遍历的步骤如下:- 首先判断当前节点是否为空,若为空则返回;- 递归遍历左子树;- 访问当前节点;- 递归遍历右子树。

2. 非递归实现中序遍历:非递归实现中序遍历同样需要借助栈来实现,具体步骤如下:- 将根节点入栈;- 循环执行以下步骤,直到栈为空:- 若当前节点不为空,则将当前节点入栈,并将当前节点指向其左子节点;- 若当前节点为空,则弹出栈顶节点,并访问该节点,然后将当前节点指向其右子节点。

三、后序遍历后序遍历是二叉树遍历的另一种方式,也是最后一种常见的遍历方式。

在后序遍历中,首先递归地遍历左子树,然后递归地遍历右子树,最后访问根节点。

后序遍历的应用也非常广泛,例如在二叉树的删除操作中,需要先删除子节点,再删除根节点。

用C语言编写二叉树的建立与遍历

用C语言编写二叉树的建立与遍历

用C语言编写二叉树的建立与遍历1.对题目要有需求分析在需求分析中,将题目中要求的功能进行叙述分析,并且设计解决此问题的数据存储结构,设计或叙述解决此问题的算法。

给出实现功能的一组或多组测试数据,程序调试后,将按照此测试数据进行测试的结果列出来。

如果程序不能正常运行,写出实现此算法中遇到的问题和改进方法;2.对题目要有相应的源程序源程序要按照写程序的规则来编写。

要结构清晰,重点函数的重点变量,重点功能部分要加上清晰的程序注释。

(注释量占总代码的四分之一)程序能够运行,要有基本的容错功能。

尽量避免出现操作错误时出现死循环;3.最后提供的主程序可以象一个应用系统一样有主窗口,通过主菜单和分级菜单调用课程设计中要求完成的各个功能模块,调用后可以返回到主菜单,继续选择其他功能进行其他功能的选择。

二叉树的建立与遍历[问题描述]建立一棵二叉树,并对其进行遍历(先序、中序、后序),打印输出遍历结果。

[基本要求]从键盘接受输入,以二叉链表作为存储结构,建立二叉树,并对其进行遍历(先序、中序、后序),将遍历结果打印输出。

以下是我的数据结构实验的作业:肯定好用,里面还包括了统计树的深度和叶子数!记住每次做完一个遍历还要重新输入你的树哦!#include "stdio.h"#include "string.h"#define NULL 0typedef struct BiTNode{char data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;BiTree Create(BiTree T){char ch;ch=getchar();if(ch=='#')T=NULL;else{if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))printf("Error!");T->data=ch;T->lchild=Create(T->lchild);T->rchild=Create(T->rchild); }return T;}void Preorder(BiTree T){if(T){printf("%c",T->data); Preorder(T->lchild); Preorder(T->rchild);}}int Sumleaf(BiTree T){int sum=0,m,n;if(T){if((!T->lchild)&&(!T->rchild)) sum++;m=Sumleaf(T->lchild);sum+=m;n=Sumleaf(T->rchild);sum+=n;}return sum;}void zhongxu(BiTree T){if(T){zhongxu(T->lchild);printf("%c",T->data); zhongxu(T->rchild);}}void houxu(BiTree T){if(T){houxu(T->lchild);houxu(T->rchild);printf("%c",T->data);}}int Depth(BiTree T){int dep=0,depl,depr;if(!T) dep=0;else{depl=Depth(T->lchild);depr=Depth(T->rchild);dep=1+(depl>depr?depl:depr);}return dep;}main(){BiTree T;int sum,dep;T=Create(T);Preorder(T);printf("\n");zhongxu(T);printf("\n");houxu(T);printf("\n");sum=Sumleaf(T);printf("%d",sum);dep=Depth(T);printf("\n%d",dep);}在Turbo C的环境下,先按Ctrl+F9运行程序,此时就是建立二叉树的过程,例如输入序列ABC##DE#G##F###(其中的“#”表示空,并且输入过程中不要加回车,因为回车也有对应的ASCII码,是要算字符的,但是输入完之后可以按回车退出),然后再按ALT+F5显示用户界面,这时候就能够看到结果了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验报告课程名称数据结构实验项目实验三--创建一个二叉树并输出三种遍历结果系别■计算机学院 _________________专业_______________班级/学号_____________学生姓名___________实验日期—成绩______________________________ 指导教师实验题目:实验三创建一个二叉树并输出三种遍历结果实验目的1)掌握二叉树存储结构;2)掌握并实现二叉树遍历的递归算法和非递归算法;3)理解树及森林对二叉树的转换;4)理解二叉树的应用一哈夫曼编码及WPL计算。

实验内容1)以广义表或遍历序列形式创建一个二叉树,存储结构自选;2)输出先序、中序、后序遍历序列;3)二选一应用题:1)树和森林向二叉树转换;2)哈夫曼编码的应用问题。

题目可替换上述前两项实验内容)设计与编码1)程序结构基本设计框架(提示:请根据所选定题目,描述程序的基本框架,可以用流程图、界面描述图、框图等来表示)2)本实验用到的理论知识遍历二叉树,递归和非递归的方法(应用型(提示:总结本实验用到的理论知识,实现理论与实践相结合。

总结尽量简明扼要,并与本次实验密切相关,要求结合自己的题目并阐述自己的理解和想法)3) 具体算法设计1) 首先,定义二叉树的存储结构为二叉链表存储,每个元素的数据类型Elemtype,定义一棵二叉树,只需定义其根指针。

2) 然后以递归的先序遍历方法创建二叉树,函数为CreateTree(),在输入字符时要注意,当节点的左孩子或者右孩子为空的时候,应当输入一个特殊的字符(本算法为“ #”),表示左孩子或者右孩子为空。

3) 下一步,创建利用递归方法先序遍历二叉树的函数,函数为PreOrderTreeQ,创建非递归方法中序遍历二叉树的函数,函数为InOrderTree(),中序遍历过程是:从二叉树的根节点开始,沿左子树向下搜索,在搜索过程将所遇到的节点进栈;左子树遍历完毕后,从栈顶退出栈中的节点并访问;然后再用上述过程遍历右子树,依次类推,指导整棵二叉树全部访问完毕。

创建递归方法后序遍历二叉树的函数,函数为LaOrderTree()。

(提示:该部分主要是利用C、C++ 等完成数据结构定义、设计算法实现各种操作,可以用列表分步形式的自然语言描述,也可以利用流程图等描述)4) 编码#include<stdio.h>#include<malloc.h>#include<stdlib.h>typedef char DataType;#define MaxSize 100typedef struct Node{DataType data;struct Node *lchild;struct Node *rchild;}*BiTree,BitNode;实验题目:实验三 创建一个二叉树并输出三种遍历结果/* 树的初始化 *//* 按照先序输入字符序列递归创建二叉树 */ /* 二叉树的先序遍历的递归函数声明 */ /* 二叉树的中序遍历的递归函数声明 */ /* 二叉树的后序遍历的递归函数声明 *//* 二叉树的先序遍历的非递归函数声明 */ /*二叉树的中序遍历的非递归函数声明 */ /* 二叉树的后序遍历的非递归函数声明 */void main(){BiTree T,root; InitBitTree(&T);printf(" 根据输入二叉树的先序序列创建二叉树 ('#' 表示结束 ): \n");CreateBitTree(&T);printf(" 二叉树的先序序列: \n"); printf(" 递归: \t");PreOrderTraverse(T); printf("\n"); printf(" 非递归: "); PreOrderTraverse2(T); printf("\n");printf(" 二叉树的中序序列: \n"); printf(" 递归: \t");InOrderTraverse(T); printf("\n"); printf(" 非递归: "); InOrderTraverse2(T); printf("\n");printf(" 二叉树的后序序列: \n"); printf(" 递归: \t");PostOrderTraverse(T); printf("\n"); printf(" 非递归: "); PostOrderTraverse2(T); printf("\n");}void InitBitTree(BiTree *T){*T=NULL;void InitBitTree(BiTree *T); void CreateBitTree(BiTree *T); void PreOrderTraverse(BiTree T); void InOrderTraverse(BiTree T); void PostOrderTraverse(BiTree T); void PreOrderTraverse2(BiTree T); void InOrderTraverse2(BiTree T); void PostOrderTraverse2(BiTree T);}void CreateBitTree(BiTree *T) /* 递归创建二叉树*/{DataType ch; scanf("%c",&ch); if(ch=='#') *T=NULL;else{*T=(BiTree)malloc(sizeof(BitNode)); /* 生成根结点*/if(!(*T))exit(-1);(*T)->data=ch;CreateBitTree(&((*T)->lchild));CreateBitTree(&((*T)->rchild));}}void PreOrderTraverse(BiTree T)/* 先序遍历二叉树的递归实现*/{if(T){printf("%2c",T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}}void InOrderTraverse(BiTree T)/* 中序遍历二叉树的递归实现*/{if(T){InOrderTraverse(T->lchild);printf("%2c",T->data);InOrderTraverse(T->rchild);}}void PostOrderTraverse(BiTree T)/* 后序遍历二叉树的递归实现*/{/* 构造左子树*//* 构造右子树*//* 如果二叉树不为空*//* 访问根结点*//* 先序遍历左子树*//* 先序遍历右子树*//* 如果二叉树不为空*//* 中序遍历左子树*//* 访问根结点*//* 中序遍历右子树*/if(T) /* 如果二叉树不为空*/PostOrderTraverse(T->lchild);PostOrderTraverse(T->rchild);printf("%2c",T->data);}}void PreOrderTraverse2(BiTree T)/* 先序遍历二叉树的非递归实现*/{BiTree stack[MaxSize];int top;BitNode *p;top=0;p=T;while(p!=NULL||top>0){while(p!=NULL)*/{printf("%2c",p->data);stack[top++]=p;p=p->lchild;}if(top>0){p=stack[--top];p=p->rchild;}}}void InOrderTraverse2(BiTree T)/* 中序遍历二叉树的非递归实现*/{BiTree stack[MaxSize];int top;BitNode *p; /* 后序遍历左子树*//* 后序遍历右子树*//* 访问根结点*//* 定义一个栈,用于存放结点的指针*/ /*定义栈顶指针*//* 定义一个结点的指针*//* 初始化栈*//*如果p 不空,访问根结点,遍历左子树/* 访问根结点*//*将p 入栈*//* 遍历左子树*//* 如果栈不空*//* 栈顶元素出栈*/ /*遍历右子树*//* 定义一个栈,用于存放结点的指针*//* 定义栈顶指针*//* 定义一个结点的指针*/top=0;p=T;while(p!=NULL||top>0){while(p!=NULL)*/{stack[top++]=p;p=p->lchild;}if(top>0){p=stack[--top];printf("%2c",p->data);p=p->rchild;}}}/* 初始化栈*//*如果p 不空,访问根结点,遍历左子树/*将p 入栈*//* 遍历左子树*//* 如果栈不空*//* 栈顶元素出栈*//* 访问根结点*//* 遍历右子树*/void PostOrderTraverse2(BiTree T) /* 后序遍历二叉树的非递归实现*/{BiTree stack[MaxSize]; int top;BitNode *p,*q;top=0; p=T,q=NULL;while(p!=NULL||top>0) { while(p!=NULL) 子树*/{ stack[top++]=p;p=p->lchild;} if(top>0){/* 定义一个栈,用于存放结点的指针*/ /*定义栈顶指针*//* 定义结点的指针*//* 初始化栈*//* 初始化结点的指针*//* 如果p 不空,访问根结点,遍历左/*将p 入栈*//* 遍历左子树*//* 如果栈不空*/p=stack[top-1]; /* 取栈顶元素*/if(p->rchild==NULL||p->rchild==q) /* 如果p 没有右孩子结点,或右孩子结点已经访问过*/{ printf("%2c",p->data); /* 访问根结点*/ q=p;p=NULL; top--;}else p=p->rchild;}}}(提示:该部分主要是将算法转化为C、C++ 程序,设计主函数完成对各成员函数的调用;设计人机界面,每一步需要用户操作的提示以及每一次用户操作产生的预期结果)四、运行与测试1) 在调试程序的过程中遇到什么问题,是如何解决的?在调试程序的过程中,遇到最大的问题就是中序和后序不能正确表示答案,最后发现是因为两个函数的错误导致。

相关文档
最新文档