中序遍历

20182322 2019-2020-1 《数据结构与面向对象程序设计》第9周学习总结

点点圈 提交于 2019-12-05 00:08:29
教材第16章学习内容总结 本章的内容主要讲树,顾名思义树与队列、栈、列表最大的区别就在于,树是一种非线性结构,其元素是一种层次结构存放。 树: 用于描述树相关的术语有非常多,除了之前常用的结点(node)还有边(edge)、孩子、兄弟等等,其中我认为比较重要的有: 内部节点:非根节点,且至少有一个子结点 同胞节点:属于同一节点的子结点 叶节点:不包含任何子节点的结点 树的分类:可以有非常多的分类方式,但是最重要的标准是任一结点可以具有的最大孩子数目,成为度(order),n元树的定义也是由此定义的 树的数组实现:因为数组实现树比较麻烦,所以在树的数组实现中书上同样模拟了链接策略,如图所示。 树的遍历, 前序遍历:从根节点开始访问每一个节点及其孩子。如图: 中序遍历:从根节点开始(注意并不是先访问根节点),中序遍历根节点的左子树,然后是访问根节点,最后中序遍历根节点的右子树。如图: 后序遍历:从左到右先叶子后节点的方式遍历访问左右子树,最后访问根节点。如图: 层序遍历:从树的第一层,也就是根节点开始访问,从上到下逐层遍历,在同一层中,按从左到右的顺序结点逐个访问。如图: 二叉树 (二叉树极其重要,以至于用三级标题来写它,而不是一般的一个点。)二叉树又名二元树,它的每一个结点最多具有两个孩子结点。 二叉树 (二叉树极其重要,以至于用三级标题来写它,而不是一般的一个点。)二叉树又名二元树

【algo&ds】【吐血整理】4.树和二叉树、完全二叉树、满二叉树、二叉查找树、平衡二叉树、堆、哈夫曼树、B树、字典树、红黑树、跳表、散列表

前提是你 提交于 2019-12-04 20:51:38
本博客内容耗时4天整理,如果需要转载,请注明出处,谢谢。 1.树 1.1树的定义 在计算机科学中,树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点: 每个节点都只有有限个子节点或无子节点; 没有父节点的节点称为根节点; 每一个非根节点有且只有一个父节点; 除了根节点外,每个子节点可以分为多个不相交的子树; 树里面没有环路(cycle) 1.2常见术语 节点的度 :一个节点含有的 子树的个数 称为该节点的度; 树的度 :一棵树中,最大的节点度称为树的度; 叶节点 或 终端节点 :度为零的节点; 非终端节点 或 分支节点 :度不为零的节点; 父亲节点 或 父节点 :若一个节点含有子节点,则这个节点称为其子节点的父节点; 孩子节点 或 子节点 :一个节点含有的子树的根节点称为该节点的子节点; 兄弟节点 :具有相同父节点的节点互称为兄弟节点; 节点的 层次 :从根开始定义起,根为第1层,根的子节点为第2层,以此类推; 深度 :对于任意节点n,n的深度为从根到n的唯一路径长,根的深度为0; 高度 :对于任意节点n,n的高度为从n到一片树叶的最长路径长,所有树叶的高度为0;

C++ 二叉树的创建于遍历

旧城冷巷雨未停 提交于 2019-12-04 13:27:32
头文件(bitree.hpp) 1 #pragma 2 #include<iostream> 3 #include<queue> 4 #include<vector> 5 #include<stack> 6 using namespace std; 7 struct TreeNode 8 { 9 int NodeData; 10 TreeNode *pLeft; 11 TreeNode *pRight; 12 TreeNode(int x) :NodeData(x), pLeft(NULL),pRight(NULL) {} 13 }; 14 class Mytree 15 { 16 public: 17 void insertTree(TreeNode* proot,int n) 18 { 19 20 } 21 void PreOrderno(TreeNode *T)//前序遍历,递归 22 { 23 if (!T) 24 return; 25 if (T) 26 { 27 cout << T->NodeData << endl; 28 PreOrderno(T->pLeft); 29 PreOrderno(T->pRight); 30 31 } 32 33 } 34 void PreOrder(TreeNode *T)//非递归,前序遍历 35 { 36 if (T ==

二叉树的层次遍历

一个人想着一个人 提交于 2019-12-04 10:50:19
如何遍历一棵树 有两种通用的遍历树的策略: 深度优先搜索(DFS) 在这个策略中,我们采用深度作为优先级,以便从跟开始一直到达某个确定的叶子,然后再返回根到达另一个分支。 深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序被细分为先序遍历,中序遍历和后序遍历。 宽度优先搜索(BFS) 我们按照高度顺序一层一层的访问整棵树,高层次的节点将会比低层次的节点先被访问到。 下图中的顶点按照访问的顺序编号,按照 1-2-3-4-5 的顺序来比较不同的策略。 本问题就是用宽度优先搜索遍历来划分层次:[[1], [2, 3], [4, 5]]。 方法 1:递归 算法 最简单的解法就是递归,首先确认树非空,然后调用递归函数 helper(node, level),参数是当前节点和节点的层次。程序过程如下: 输出列表称为 levels,当前最高层数就是列表的长度 len(levels)。比较访问节点所在的层次 level 和当前最高层次 len(levels) 的大小,如果前者更大就向 levels 添加一个空列表。 将当前节点插入到对应层的列表 levels[level] 中。 递归非空的孩子节点:helper(node.left / node.right, level + 1)。 实现 class Solution { List<List<Integer>> levels = new

用非递归的方法中序遍历二叉树

半世苍凉 提交于 2019-12-04 10:33:19
写这篇纯属个人兴趣了😂 要遍历二叉树的话优先推荐用递归的方法 在传统的遍历二叉树时,如果要使用递归的方法 前序遍历: void FrontOrder(biTree *s) {   if(s){     printf("%d",s->data);     FrontOrder(s->lchild);     FrontOrder(s->rchild);   } } 中序遍历: void InOrder(biTree *s) {   if(s){     InOrder(s->lchild);     printf("%d",s->data);     InOrder(s->rchild);   } } 后续遍历: void PostOrder(biTree *s) {   if(s){     PostOrder(s->lchild);     PostOrder(s->rchild);     printf("%d",s->data);   } } 用栈的话👇,话不多说,上代码 #include <stdio.h> #define maxsize 24 typedef struct node{ char data; struct node *lchild; struct node *rchild; }biTree; biTree * Q[maxsize]; biTree *

二叉树遍历的递归实现(先序、中序、后序和层次遍历)

我的梦境 提交于 2019-12-04 09:35:41
由二叉树的定义可知,一棵二叉树由根结点、左子树和右子树三部分组成。因此,只要遍历了这三个部分,就可以实现遍历整个二叉树。若以D、L、R分别表示遍历根结点、左子树、右子树,则二叉树的递归遍历可以有一下三种方式: 先序遍历(DLR) 先序遍历的递归过程为 (1)访问根结点 (2)先序遍历根结点的左子树 (3)先序遍历根结点的右子树 举例: 代码: void PreOrder(BiTree bt) { if(bt ==NULL)return; //递归的结束条件----某结点为空时 printf("bt->data); //这里用printf data表示访问结点的数据域 PreOrder(bt->lchild); //递归遍历左孩子 PreOrder(bt->rclild); //递归遍历右孩子 } 中序遍历(LDR ) (1)中序遍历根结点的左子树 (2)访问根结点 (3)中序遍历根结点的右子树 举例: 代码: void PreOrder(BiTree bt) { if(bt ==NULL)return; //递归的结束条件----某结点为空时 PreOrder(bt->lchild); //递归遍历左孩子 printf("bt->data); //这里用printf data表示访问结点的数据域 PreOrder(bt->rclild); //递归遍历右孩子 } 后序遍历(LRD)

23 遍历二叉树的非递归算法

烈酒焚心 提交于 2019-12-04 09:33:57
例子:中序遍历非递归算法 实现代码: //中序遍历的非递归算法 int InOrderTraverse_No_DiGui(BiTree T){ BiTree p; //顶底指向二叉树中节点的游标 InitStack(S); //初始化栈 p = T; //p指向所给的二叉树根节点 while(p || !StackEmpty(S)){ if(p){ //若当前节点非空 Push(S, p); //将当前节点入栈 p = p->lchild; //游标指向当前节点的左孩子 }else{ Pop(S, q); //出栈,将栈顶节点返回到一个二叉树节点类型的变量 q 中 printf("%c", q->data); //输出该节点的数据域 p = q->rchild; //游标指向当前节点的右孩子 } }//while return 1; //遍历结束 } View Code 来源: https://www.cnblogs.com/CPU-Easy/p/11854078.html

树和二叉树一篇就搞定!

[亡魂溺海] 提交于 2019-12-04 03:42:46
二叉树铺垫——树 前面几篇文章我们主要介绍的线性表,栈,队列,串,等等,都是一对一的 线性结构 ,而今天我们所讲解的 “树” 则是一种典型的 非线性结构 ,非线性结构的特点就是,任意一个结点的直接前驱,如果存在,则一定是唯一的,直接后继如果存在,则可以有多个,也可以理解为一对多的关系,下面我们就先来认识一下树 树的概念 下图我们日常生活中所见到的树,可以看到,从主树干出发,向上衍生出很多枝干,而每一根枝干,又衍生出一些枝丫,就这样组成了我们在地面上可以看到的树的结构,但对于每一个小枝丫来讲,归根结底,还是来自于主树干的层层衍生形成的。 我们往往需要在计算机中解决这样一些实际问题 例如: 用于保存和处理树状的数据,例如家谱,组织机构图 进行查找,以及一些大规模的数据索引方面 高效的对数据排序 先不提一些复杂的功能,就例如对于一些有树状层级结构的数据进行建模,解决实际问题,我们就可以利用 “树” 这种结构来进行表示,为了更符合我们的习惯,我们一般把 “树” 倒过来看,我们就可以将其归纳为下面这样的结构,这也就是我们数据结构中的 “ 树” 树中的常见术语 结点 :包含数据项以及指向其他结点的分支,例如上图中圆 A 中,既包含数据项 A 又指向 B 和 C 两个分支 特别的,因为 A 没有前驱,且有且只有一个,所以称其为根结点 子树 :由根结点以及根结点的所有后代导出的子图称为树的子树

第106题:从中序与后序遍历序列构造二叉树

拥有回忆 提交于 2019-12-04 03:39:11
一. 问题描述 根据一棵树的中序遍历与后序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树: 3 / \ 9 20 / \ 15 7 二. 解题思路 本题思路:采用中序和后序遍历的特性进行求解,跟第105题几乎完全相同,只是把前序第一个必定是根节点,改成后序最后一个必定是根节点这点区别,没啥说的,具体可看第105题。 三. 执行结果 执行用时 :21 ms, 在所有 java 提交中击败了37.40%的用户 内存消耗 :51.4 MB, 在所有 java 提交中击败了8.79%的用户 四. Java代码 class Solution { public TreeNode buildTree(int[] inorder, int[] postorder) { if(postorder.length>0) { TreeNode root =new TreeNode(postorder[postorder.length-1]); List<Integer> order=new ArrayList<Integer>(); for(int i=0;i<inorder.length;i++) { order.add(inorder[i]);

leetcode 99:恢复二叉搜索树

一曲冷凌霜 提交于 2019-12-04 02:36:59
方法一:首先使用中序遍历将所有的节点和节点的值存起来,如果是搜索二叉树节点值的数组应该是升序的,找到不是升序的点,交换节点的值,空间复杂度为O(n) void inorder(TreeNode*root,std::vector<TreeNode*>&list,std::vector<int> &vals){ if(root==NULL) return; inorder(root->left,list,vals); list.push_back(root); vals.push_back(root->val); inorder(root->right,list,vals); } void recoverTree(TreeNode*root){ std::vector<TreeNode*>list; std::vector<int>vals; inorder(root,list,vals); std::vector<int> node; for(int i=0;i<vals.size()-1;){ if(vals[i]>vals[i+1]) { node.push_back(i); i=i+2; if(node.size()==2) break; }else i=i+1; } if(node.size()==1) { int c=node.back(); node.clear();