二叉树遍历

二叉树的基本操作C++

匿名 (未验证) 提交于 2019-12-03 00:26:01
本文用C++语言写了二叉树的基本操作,包括二叉树的四种遍历方式的递归和非递归写法,二叉查找树的插入,删除,构建,路径搜索,序列化和反序列化,是否镜像等操作,仅供参考。 #include<iostream> #include<stack> #include<queue> #include<vector> #include<string> using namespace std; struct TreeNode { TreeNode *left, *right; int val; TreeNode(int x) :val(x), left(NULL), right(NULL){} }; //前序遍历的递归写法 void helper1(TreeNode *root, vector<int> &res) { if (!root) return; res.push_back(root->val); helper1(root->left, res); helper1(root->right, res); } vector<int> preTraversalRecur(TreeNode *root) { vector<int> res; helper1(root, res); return res; } //前序遍历的非递归写法 vector<int> preTraversalNonrecur

BST树的插入,删除,查找(递归和非递归),先序,中序,后序(递归和非递归)

匿名 (未验证) 提交于 2019-12-03 00:18:01
关于二叉查找树的操作还是挺重要的,所以在此实现了BST的相关操作。 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。 首先实现BST的遍历操作吧,一般面试也喜欢问,比较重要的是各个遍历的非递归操作,在这里也就只实现非递归操作; 其中先序和中序遍历的非递归操作比较相似,主要思想就是将每个节点当做一个根节点进行操作。后序遍历稍微不同。下面进行代码的演示,以及相关解释: 首先针对先序遍历 Stack<TreeNode> snode = new Stack<>(); TreeNode p = root; while (!snode.isEmpty() || p != null) { if (p!=null) { System.out.print(p.value+" "); snode.push(p); p = p.left; }else{ TreeNode q = snode.pop(); p = q.right; } } 可以看到代码中利用了一个栈进行辅助,因为先序遍历的顺序是根-左-右,所以在向左节点进行遍历的时候,将节点输出,同时将节点放入栈中

根据先序遍历和中序遍历建立二叉树

匿名 (未验证) 提交于 2019-12-03 00:14:01
˼· 先序遍历服从规则 “根左右” ,所以由此可知,对于一个先序遍历得到的数组,第一个元素一定是 根节点 ; 中序遍历服从规则 ”左根右“ ,所以由此可知,对于一个中序遍历得到的数组,根节点左边的元素都属于根节点的 左子树 ,而根节点右边的元素都属于根节点的 右子树 ; 所以,我们可以先通过先序遍历的第一个元素确定根节点,然后通过中序遍历结合根节点,获得当前根节点的左右子树,再将子树看成一棵独立的树,继续使用先序遍历判断根节点,中序遍历判断子树的方式,最终建立起整棵树; 假设有一棵二叉树,先序遍历为 {1,2,4,7,3,5,6,8} ,中序遍历为 {4,7,2,1,5,3,8,6} ,则建树过程如下: 首先,通过先序遍历可知树的根节点为 1 ,则在中序遍历中,1左边的元素 4,7,2 即为根的左子树的元素,而 1 右边的元素 5,3,8,6 即为根节点的右子树; 对于左子树 4,7,2 来说,在先序遍历中,这三个点的顺序为 2,4,7 ,则 2 为根节点,而在中序遍历中, 4,7 均在 2 的左边,则 4,7 均为以 2 为根树的左子树,且没有右子树; 对于 4,7 这两个节点来说,先序遍历中, 4 节点在7节点之前,所以 4 为根节点,而 7 作为子树,在中序遍历中, 7 在 4 之后,所以 7 为右子树; 对于根节点 1 的右子树 5,3,8,6 来说,在先序遍历中, 3

树-基本概念,遍历,表示法

匿名 (未验证) 提交于 2019-12-03 00:13:02
树的基本概念和常用术语 节点的度:一个结点的儿子结点个数称为该节点的度 树的度:一棵树的度是指该树中结点的最大度数。如上图的树的度是3 叶节点或终端节点:度为零的节点。如上图中E,I,J,C,G,H是叶节点 非终端节点或分支节点:度不为零的节点。除根节点外的分支节点都叫做内部节点。 路径:若存在树中的一个节点序列k1,k2,…,kj,使得结点ki是ki+1的父结点(1<=i<j),则称该结点序列是树中从结点k1到结点kj的一条路径。 路径长度:路径所经过的边的数目。 节点高度:从该结点到各叶结点的最长路径长度,例如上图中B,C,D的高度分别是2,0,1 树的高度: (这里规定单根的高度为0) 根结点的高度 结点的深度(或层数):从树根到任一结点n有唯一的路径,称该路径的长度为结点n的深度(或层数)。从根结点算起,根为第0层,它的孩子为第1层…… 森林:m(m>=0)棵互不相交的树的集合 树的遍历 前序遍历:先访问树根n,然后依次前序遍历T1,T2,…,Tk。 中序遍历:先中序遍历T1,然后访问树根n,接着依次对T2,T3,…,Tk 进行中序遍历。 后序遍历:先依次对T1,T2,…,Tk进行后序遍历,最后访问树根n。 树的表示方法 父节点数组表示法 (1)树中的结点数字化为它们的编号1,2,…,n。 (2)用一个一维数组存储每个结点的父结点。即:father[k

二叉树

匿名 (未验证) 提交于 2019-12-03 00:06:01
  二叉树 是一种特殊的树,它具有以下 特点 : 左子树 与 右子树 ,次序不能颠倒。   满二叉树 作为一种特殊的二叉树,它是指:所有的分支节点都存在左子树与右子树,并且所有的叶子节点都在同一层上。其 特点 有: 2 h 1 h h 为树的深度。     h h ,除第 h h 层外,其它各层 ( 1 ~ h 1 ) h h 层所有的结点都连续集中在最左边,这就是 完全二叉树 。其具有以下 特点 :    二、二叉树的相关性质 i i 层上,至多有 2 i 1 ( i ≥ 1 ) (i≥1) 。 h h 的二叉树上最多有 2 h 1 ( k ≥ 1 ) (k≥1) 。 n 0 n0 ,度数为 2 2 的节点个数为 n 2 n2 ,则有: n 0 = n 2 + 1 n0=n2+1 。 n n 个的结点的完全二叉树的深度为 log 2 n + 1 n n 个节点的完全二叉树的节点按层次序编号,对任一层的节点 i , ( 1 ≥ i ≥ n ) i,(1≥i≥n) 有: i = 1 i=1 ,则节点是二叉树的根,无双亲,如果 i > 1 i>1 ,则其双亲节点为 i / 2 2 i > n 2i>n 那么节点i没有左孩子,否则其左孩子为 2 i 2i 。 2 i + 1 > n 2i+1>n 那么节点没有右孩子,否则右孩子为 2 i + 1 2i+1 。 三、二叉树的数据结构

二叉树算法题

匿名 (未验证) 提交于 2019-12-03 00:05:01
二叉树层次遍历 //思路 特殊情况 ,根节点为null,深度为0,return 0 借助队列,队列储存每一层的所有节点, 先保存数组长度,用于控制依次遍历循环――遍历每一个节点保存值,该节点的所有子结点从队尾入队,访问过的节点从头出队 注意――需要先把width存下来,用于for循环的结束标志,因为for循环里面直接操作了queue,不能去都不敢动态获取 队列初始值为root,对每一层都要进行上述遍历――while循环控制,队列空代表叶节点这一层遍历完成,此时遍历结束,退出循环 每次循环开始前初始化一个curNodes储存该层所有节点,每次循环结束,将curNodes压入result var levelOrder = function(root) { if (root === null) return []; //空树 var result = [], queue = [root]; while (queue.length) { let width = queue.length; //需要先把width存下来,用于for循环,for循环里面直接操作了数组 let curNodes = []; for (let i = 0; i < width; i++) { let node = queue.shift(); curNodes.push(node.val); node.left ?

二叉树的创建和遍历

匿名 (未验证) 提交于 2019-12-02 23:56:01
二叉树创建:   1.创建树的结点TreeNode,包含结点的编号no,结点的名字name,左子树left,右子树right,    二叉树遍历:   1,先序遍历:先输出根节点,再递归左子树,然后递归右子树   2,中序遍历:先递归左子树,然后输入根节点,再递归右子树   3,后序遍历:先递归左子树,再递归右子树,然后输出根节点 实验:   创建如下的二叉树并遍历    代码 package Tree; public class BinaryTreeDemo { public static void main(String[] args) { BinaryTree binaryTree = new BinaryTree(); //创建结点 TreeNode root = new TreeNode(1,"宋江"); TreeNode treeNode2 = new TreeNode(2,"林冲"); TreeNode treeNode3 = new TreeNode(3,"吴用"); TreeNode treeNode4 = new TreeNode(4,"关胜"); TreeNode treeNode5 = new TreeNode(5,"卢俊义"); //创建树结构 root.setLeft(treeNode2); root.setRight(treeNode3);

LintCode66. 二叉树的前序遍历

匿名 (未验证) 提交于 2019-12-02 23:42:01
描述 给出一棵二叉树,返回其节点值的前序遍历。 首个数据为根节点,后面接着是其左儿子和右儿子节点值,"#"表示不存在该子节点。 节点数量不超过20 您在真实的面试中是否遇到过这个题? 样例 样例 1: 输入:{1,2,3} 输出:[1,2,3] 解释: 1 / 2 3 它将被序列化为{1,2,3} 前序遍历 样例 2: 输入:{1,#,2,3} 输出:[1,2,3] 解释: 1 2 / 3 它将被序列化为{1,#,2,3} 前序遍历 /** * Definition of TreeNode: * public class TreeNode { * public int val; * public TreeNode left, right; * public TreeNode(int val) { * this.val = val; * this.left = this.right = null; * } * } */ public class Solution { /** * @param root: A Tree * @return: Preorder in ArrayList which contains node values. */ public List<Integer> preorderTraversal(TreeNode root) { // write your

数据结构――二叉树的遍历

匿名 (未验证) 提交于 2019-12-02 23:38:02
对二叉树的遍历进行实现的算法: (1)定义二叉树的二叉链表存储结构。 (2)编写建立一棵二叉树算法。 (3)编写中序遍历二叉树算法。 (4)编写后序遍历二叉树算法。 (5)编写算法主程序。 (6)调试运行,记录结果。 编写头文件 Bitree.h #include<stdio.h> #include<stdlib.h> #include<malloc.h> #define OK 1 #define OVERFLOW -2 #define INFEASIBLE -1 #define TRUE 1 #define FALSE 0 #define ERROR 0 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 typedef char TElemType; typedef int Status; //二叉树的二叉链表存储表示 typedef struct BiTNode { TElemType data; struct BiTNode * lchild,* rchild; } BiTNode,* BiTree; //创建二叉树 Status CreatBiTree(BiTree &T){ char ch; scanf("%c",&ch); if (ch == '#') T=NULL; else { if (!(T=(BiTree

数据结构-二叉树遍历

匿名 (未验证) 提交于 2019-12-02 22:59:29
这篇博文主要是研究二叉树遍历的递归与非递归算法,有兴趣的小伙伴可以了解下! 二叉树的递归遍历(深度优先遍历) 先来张图,看看各结点遍历时的情况: 二叉树深度优先遍历总结( 分别为第一次,第二次,第三次进入某个结点 ): 先序遍历:先访问根结点,然后先序遍历左子树,最后先序遍历右子树; 根->左->右 中序遍历:先中序遍历左子树,然后访问根结点,最后中序遍历右子树; 左->根->右 后续遍历:先后序遍历左子树,然后后序遍历右子树,最后访问根结点; 左->右->根 递归遍历内部有系统栈,其作用: 1.保护现场(类似存档) 2.恢复现场(类似读档) 递归遍历代码比较简单,先、中、后序遍历递归代码基本相似,总代码: void r(BTNode *p) { if (p != NULL) { //第一次进入-先序 r(p->lchild); //第二次进入-中序 r(p->rchild); //第三次进入-后序 } } 先序遍历递归函数: void r(BTNode *p) { if (p != NULL) { visit(p); r(p->lChild); r(p->rChild); } } 二叉树的非递归遍历(深度优先遍历) 须知:需要自定制辅助栈 1.先序遍历非递归: 1).利用辅助栈将根节点入栈,出栈操作,访问该节点,将其右、左孩子分别入栈(每次访问节点后,对其左、右孩子需要做一个检测