中序遍历

[leetcode] 99. 恢复二叉搜索树

让人想犯罪 __ 提交于 2019-12-04 02:32:06
99. 恢复二叉搜索树 一开始想了好久没有什么好思路,去网上搜了一下,原来是中序遍历。 二叉搜索树的中序遍历是个(递增)有序数列,利用这个特性,我们可以很巧妙的解决这个题。 先看第二个例子,中序遍历后是:13245,观察发现只有一处发生了降序,只在第二位与第三位发生了降序情况,说明这两个数为异常数,交换3和2的位置重新中序遍历:12345 第一个例子,中序遍历是:321,观察发现有两处发生了降序,第一到第二位,以及第二到第三位,这种情况下交换第一位与第三位即可 实际上题目中只有两个节点被交换了,所以降序情况最多也只会出现两处。所以分两种情况处理即可。 我们再造个例子,看的更直观点: [10 17 15 1 8 12 5] 中序遍历 1 17 8 10 12 15 5 17与3发生了降序,15与5发生了降序,我们将第一个降序的前一个元素与第二个降序的后一个元素,进行交换即可。 当只有一次降序出现时(可以理解为两个降序挤到了一块嘛),降序的前一个元素与降序的后一个元素,进行交换即可。 代码 class Solution { TreeNode p, q, last; void middle(TreeNode root) { if (root == null) return; middle(root.left); if (last != null && last.val > root

Leetcode:99.恢复二叉搜索树

做~自己de王妃 提交于 2019-12-04 02:29:21
二叉搜索树中的两个节点被错误地交换。请在不改变其结构的情况下,恢复这棵树。 示例 1: 输入: [1,3,null,null,2] 1 / 3 \ 2 输出: [3,1,null,null,2] 3 / 1 \ 2 示例 2: 输入: [3,1,4,null,null,2] 3 / \ 1 4 / 2 输出: [2,1,4,null,null,3] 2 / \ 1 4 / 3 解题思路: 二叉搜索树:中序遍历中没有逆序对。如果知道什么是中序遍历,还有二叉搜索树,本题只能算是easy。 按照题意只交换了二叉树的两个结点,这也就意味着是排序数组中交换了两个元素的位置,这么一想就会变得容易很多。 1. 交换的两个元素中序遍历相邻。这时只会出现一个逆序对,交换两个逆序对结点的的val即可。 2. 两个元素在中序遍历数组中不相邻。会出现两个逆序对,我们只需记录第一个逆序对的第一个结点,以及第二个逆序对的第二个结点即可,最后交换两个结点的val即可。 只需要记录逆序对的位置即可,因此仅用了常数个空间。 C++代码 #define hasLChild(x) (!(x->left==NULL)) #define hasRChild(x) (!(x->right==NULL)) class Solution { public: void recoverTree(TreeNode* root) { /

LeetCode099——恢复二叉搜索树

旧时模样 提交于 2019-12-04 02:29:10
我的LeetCode代码仓: https://github.com/617076674/LeetCode 原题链接: https://leetcode-cn.com/problems/recover-binary-search-tree/description/ 题目描述: 知识点:二叉搜索树、中序遍历 思路一:中序遍历 这个思路和 LeetCode098——验证二叉搜索树 中的思路二是一致的。 对于一棵二叉搜索树而言,其中序遍历的结果是一个递增序列。我们保存原二叉搜索树中序遍历的结果。再对该结果进行排序后得到另一个序列,比较两个序列中的不同的两个值,即为需要交换的两个错误节点。 这里我采用的是递归的形式实现中序遍历,更多中序遍历算法请见 LeetCode094——二叉树的中序遍历 。 时间复杂度是O(nlogn),其中n为树中的节点个数。空间复杂度也是O(n)。 JAVA代码: public class Solution { List<TreeNode> list; public void recoverTree(TreeNode root) { list = new ArrayList<>(); inorderTraversal(root); List<TreeNode> tempList = new ArrayList<>(list); Collections.sort

不一样的二叉树遍历(小学生都会)

百般思念 提交于 2019-12-04 01:46:46
二叉树遍历 二叉树的遍历分为三种,分别是前序遍历,中序遍历和后序遍历。(在这里,我会介绍两种方法) 前序遍历:先根后左子树最后右子树。 中序遍历:先左子树后根最后右子树。 后序遍历:先左子树后右子树最后根。 举个中序遍历例子 原图网址: https://img2018.cnblogs.com/blog/1706194/201910/1706194-20191006152149771-1726377171.png 其它的遍历可以以此类推。这是标准的二叉树遍历方法。 高端方法 刚才的做法很标准,也很好理解,但有些慢。下面的方法显然要省时,简单一些。 -----------------------------------------------------华丽的下划线-------------------------------------------------------- 还以这幅图为例 我们把这颗树以根节点为起点圈起来。 当这条线经过一个节点的前方时,则这个点为前序遍历的一个点。 当这条线经过一个节点的中间时,则这个点为中序遍历的一个点。 当这条线经过一个节点的后方时,则这个点为后序遍历的一个点。 还以中序遍历为例,经过点的顺序为BDCEHGKF。 高 端大气上档次, 我用这个方法压线过了初赛。 不要问我原理,我也不知道。 来源: https://www.cnblogs.com

第105题:从前序与中序遍历序列构造二叉树

拥有回忆 提交于 2019-12-04 00:46:23
一. 问题描述 根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3 / \ 9 20 / \ 15 7 二. 解题思路 本题思路:了解前序遍历和中序遍历的特点并利用递归算法进行求解。前序特点:第一个元素必定是根节点,而中序遍历的特点是,根节点左右必定是左右子树的节点的集合。 步骤一:构建递归函数(前序遍历数组:preorder,int num 根节点在前序遍历数组的index值,当前中序遍历的list,root,当前根节点) 步骤二:通过preorder[num]找到当前中序遍历list中的左右子树所有值,并将左子树集合放入leftlist中,右子树集合放入rightlist中。 步骤三:通过前序中序原理,找到左子树集合和右子树集合的当前根节点root.left和root.right。并将num值变成当前根节点值的index。重复步骤一重复递归函数(preorder,newleftnum,leftlist,root.left)和(preorder,newrightnum,rightlist,root.right) 步骤四:当list中只剩下根节点时,则返回,最后输出root。 三. 执行结果

数据结构学习--Java遍历二叉树

柔情痞子 提交于 2019-12-03 23:56:29
一、遍历树 遍历树是根据一个特定的顺序访问树的每一个节点,根据顺序的不同分为前序、中序、后序遍历三种。 二、前序遍历   1、访问根节点   2、前序遍历左子树   3、前序遍历右子树 三、中序遍历   1、中序遍历左子树   2、访问根节点   3、中序遍历右子树 四、后序遍历   1、后序遍历左子树   2、后序遍历右子树   3、访问根节点 代码实现 package com.example.deer;public class Tree { //根节点 public Node root; /** * 插入节点 * @param value */ public void insert(long value,String sValue){ //封装节点 Node newNode = new Node(value,sValue); //引用当前节点 Node current = root; //引用父节点 Node parent; //如果root为null,也就是第一次插入的时候 if(root == null){ root = newNode; return; }else{ while (true){ //父节点指向当前节点 parent = current; //如果当前指向的节点数据比插入的要大,则向左走 if(current.data > value){ current =

二叉树的存储结构以及遍历

依然范特西╮ 提交于 2019-12-03 23:45:35
一、二叉树的存储结构 ————顺序存储(一维数组)——— 1 #define MaxSize 100 //假设二叉树最大编号为99 2 typedef char DataType; //定义二叉树节点的数据类型,假设为char型 3 typedef struct{ 4 DataType data[MaxSize]; 5 int biTreeNum; //二叉树的节点个数 6 }SeqBiTree; ——————二叉链表———————— 1 typedef char DataType; 2 typedef struct BiNode{ 3 DataType data; 4 struct BiNode * lchild,* rchild; 5 }BiNode; 二、二叉树的遍历 遍历过程 转载自https://mp.weixin.qq.com/s/HXce4H21Gbu_O9ciXzJQYw ————深度优先遍历———— 1.前序遍历 2.中序遍历 3.后序遍历 ————广度优先遍历———— 4.层序遍历 总结:a.我们提到的四种遍历方式,其实都是在把树种的结点编程某种意义上的线性序列,这样给程序执行带来了好处。 b.前序、中序、后序遍历最根本的区别就是双亲结点的访问时机——前序是先访问双亲结点,然后左孩子,最后右孩子;中序是左孩子,双亲,右孩子;后序是左孩子、右孩子最后双亲结点。 c

PHP 高级面试115题汇总(含答案)

左心房为你撑大大i 提交于 2019-12-03 17:29:26
1、给你四个坐标点,判断它们能不能组成一个矩形,如判断 ([0,0],[0,1],[1,1],[1,0]) 能组成一个矩形。 勾股定理,矩形是对角线相等的四边形。只要任意三点不在一条直线上,任选一点,求这一点到另外三点的长度的平方,两个短的之和如果等于最长的,那么这就是矩形。 2、写一段代码判断单向链表中有没有形成环,如果形成环,请找出环的入口处,即 P 点 1 /* 2 *单链表的结点类 3 */ 4 class LNode{ 5 //为了简化访问单链表,结点中的数据项的访问权限都设为public 6 public int data; 7 public LNode next; 8 } 9 10 class LinkListUtli { 11 //当单链表中没有环时返回null,有环时返回环的入口结点 12 public static LNode searchEntranceNode(LNode L) 13 { 14 LNode slow=L;//p表示从头结点开始每次往后走一步的指针 15 LNode fast=L;//q表示从头结点开始每次往后走两步的指针 16 while(fast !=null && fast.next !=null) 17 { 18 if(slow==fast) break;//p与q相等,单链表有环 19 slow=slow.next; 20 fast

两序遍历递归建立二叉树

怎甘沉沦 提交于 2019-12-03 16:59:34
前序中序遍历建立二叉树 1 Node * createTree1(string pres, string cens) { 2 if(pres.size() == 0 || cens.size() == 0) { 3 return nullptr; 4 } 5 Node * node = new Node(); 6 node->data = pres.at(0); 7 int key = cens.find(pres.at(0)); 8 9 string mpres = pres.substr(1, key); 10 string mcens = cens.substr(0, key); 11 node->left = createTree1(mpres,mcens); 12 13 mpres = pres.substr(key+1, pres.size()-key-1); 14 mcens = cens.substr(key+1, cens.size()-key-1); 15 node->right = createTree1(mpres,mcens); 16 return node; 17 }; View Code 中序后序遍历建立二叉树 后序中序遍历就是将前序中序遍历中的对前序的操作转换为对后序的操作,前序从第一个开始取,后序从后往前取。对中序操作不变 来源: https:/

静态创建二叉树及其遍历

对着背影说爱祢 提交于 2019-12-03 10:07:52
我们以这个二叉树为例 1.构造二叉树的链式存储结构 1 struct BTNode{ 2 char data; //结点数据域 3 struct BTNode * pLchild; //左孩子指针-->指向左孩子 4 struct BTNode * pRchild; //右孩子指针-->指向右孩子 5 }; View Code 2.静态的创建二叉树 struct BTNode * createBTree() { struct BTNode* pa = (struct BTNode*)malloc(sizeof(struct BTNode)); struct BTNode* pb = (struct BTNode*)malloc(sizeof(struct BTNode)); struct BTNode* pc = (struct BTNode*)malloc(sizeof(struct BTNode)); struct BTNode* pd = (struct BTNode*)malloc(sizeof(struct BTNode)); struct BTNode* pe = (struct BTNode*)malloc(sizeof(struct BTNode)); pa->data = 'A'; pb->data = 'B'; pc->data = 'C'; pd->data