题目描述:

/**
* 给定一棵二叉搜索树,请找出其中的第k小的结点。
* 例如, (5,3,7,2,4,6,8)中,
* 按结点数值大小顺序第三小结点的值为4。
* 这是层序遍历:
* 5
* 3 7
* 2 4 6 8 思路:
二叉搜索树的中序遍历(左--中--右)就是按照从小到大进行排好序的结果,所以如果你想输出第k小的节点就是找到从左到右的第k个数就ok了!
所以这个问题可以转化为求二叉搜索树的中序遍历的方法! 递归版:
public TreeNode kthNode2(TreeNode pRoot,int k)
{
if(pRoot==null||k==0)
return null; inorder(pRoot,k);
return root;
} private void inorder(TreeNode pRoot, int k) {
if(pRoot==null)
return;
inorder(pRoot.left,k);
//返回完了之后就对应着倒数第一个节点!
cnt++;
if(cnt==k)
root = pRoot;
inorder(pRoot.right,k);
}

递归版代码解释:

其实思路很简单,但是需要人为的去在脑子里过一遍,因为是二叉搜索树,所以最最最左边的节点,一定是最小的,因此我们需要直接走到整棵树的最左边的节点,也就是2!用递归的方法如何实现呢?

inorder(pRoot.left,k); + (if(pRoot==null) return;)  两个神器搭配就可以直接走到整棵树的最左边的节点!然后接下来的任务就有意思了,进到最左边的节点之后,它一定是最小的,所以我们让全局变量cnt++;也就是说它代表了倒数第一小的节点!之后是一个if判断,if(cnt==k),root=pRoot;如果相等了代表当前节点就是你要找的节点,直接给TreeNode root赋值就可以结束,否则的话,继续进到它的右节点进行寻找!为什么这里要进右节点呢?

考虑第一次返回,说明2节点的左子树肯定为null,那么根据中序遍历  左--->中---->右的原则,你找完了中间节点,必须去到它的右子树里看看是否存在右子树!如果右子树存在,那么继续一路飙到最左边,然后count++!这才代表了倒数第二个节点的存在!当你的右子树找完之后,自然函数会返回,那么它返回的一定是上一层的中间节点3!此时依然要执行3这个节点的右节点!因为你返回上去之后,它一定是上一层的树的中间节点,而你刚刚进入下以层找的恰好是它的左子树!所以要继续找3的右子树!

这就是为什么每次count++;之后要找右子树再进入递归的原因!因为你在递归进左子树的过程中你实际上进入的是(1 子树结构的左节点,2 “根”结构的中间节点)

所以,你一旦返回就证明着你现在位于高层次树的中间节点上,接下来等着你处理的一定是右子树!!!

以上是我对递归法中序遍历二叉搜索树的一些理解!

非递归实现:

  if(pRoot==null|| k==0)
return null;
int count=0;
Stack<TreeNode> stack = new Stack<>();
while(pRoot!=null || !stack.isEmpty())
{ while(pRoot!=null)
{
stack.push(pRoot);
pRoot = pRoot.left;
}
pRoot = stack.pop();//倒数第一小的节点出来了!
count++;
if(count==k)
return pRoot;
pRoot = pRoot.right;
}
return null;
现在我觉得迭代的实现其实就是把原来递归隐式使用计算机栈的规则给显式的表示出来!
新建一个栈,while(pRoot!=null || !stack.isEmpty())
当pRoot没走到最后或者栈里面还有元素的时候我们就在这个循环里面继续进行
继续判断如果是pRoot!=null那么二话不说直接压栈到最左边的节点一样的操作!
从栈里面弹出一个节点,此时的节点就是最左边的最小值,然后count++;
后面的代码和递归版基本一致!判断等不等于k,然后继续!最关键的是最后的一行代码,pRoot = pRoot.right;
我们仍旧需要进入到它的右子树里面重复执行,此时我们会看这个条件!while(pRoot!=null||!stack.isEmpty())
它其实就是代表的两种情况 :
   1 右子树存在,那么继续压栈处理走到最左边慢慢往上升
   2 右子树不存在程序返回,那么此时栈就必须存在树节点,而此时的树节点就刚好是上层的中间节点了! 所以一个非常重要的思想是:
节点在子树里面充当的是左节点!一旦它上升到上一层树的级别,那么在这个结构里面它就是中间节点,所以必须往右子树里继续执行!
 

求二叉搜索树的第k小的节点的更多相关文章

  1. 求得二叉搜索树的第k小的元素

    求得二叉搜索树的第k小的元素 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 须知:二叉搜索树,又叫二叉排序树,二叉查找树.特点是:左子树的所有元素都小于等 ...

  2. 【Offer】[54] 【二叉搜索树的第k小节点】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 给定一棵二叉搜索树,请找出其中第k小的节点.例如,在下图的二叉搜索树里,按节点数值大小顺序,第三小节点的值是4.  牛客网刷题地址 思 ...

  3. 二叉搜索树的第k大的节点

    题目 给定一颗二叉搜索树,请找出其中的第k大的结点. 思路 如果中序遍历一棵二叉搜索树,遍历序列的数值则是递增排序,因此只需中序遍历一个二叉搜索树即可. #include <iostream&g ...

  4. 基本二叉搜索树的第K小元素

    #include<stdio.h> #include<stdlib.h> typedef struct node *btlink; struct node { int data ...

  5. [LeetCode]230. 二叉搜索树中第K小的元素(BST)(中序遍历)、530. 二叉搜索树的最小绝对差(BST)(中序遍历)

    题目230. 二叉搜索树中第K小的元素 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 题解 中序遍历BST,得到有序序列,返回有序序列的k-1号元素. 代 ...

  6. 230. 二叉搜索树中第K小的元素

    230. 二叉搜索树中第K小的元素 题意 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数. ...

  7. leetcode 二叉搜索树中第K小的元素 python

          二叉搜索树中第K小的元素     给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 说明:你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元 ...

  8. LeetCode:二叉搜索树中第K小的数【230】

    LeetCode:二叉搜索树中第K小的数[230] 题目描述 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 说明:你可以假设 k 总是有效的,1 ≤ k ...

  9. 剑指offer:二叉搜索树的第k个结点(中序遍历)

    1. 题目描述 /* 给定一棵二叉搜索树,请找出其中的第k小的结点. 例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4. */ 2. 思路 中序遍历二叉搜索树,第K个就 ...

随机推荐

  1. IntelliJ IDEA 设置检查 serialVersionUID

    IntelliJ IDEA 设置检查 serialVersionUID 背景介绍 我们在使用IntelliJ IDEA创建Java类的时候,有时候需要实现序列化接口 implements Serial ...

  2. IDEA的version control log为空,该怎么办?

    问题描述: 解决方案: 关掉IDEA,重新打开,即可药到病除

  3. ORACLE 11G使用用EXPDP导出时,空表不能导出

    11G中有个新特性,当表无数据时,不分配segment,以节省空间解决方法:1.insert一行,再rollback就产生segment了.该方法是在在空表中插入数据,再删除,则产生segment.导 ...

  4. python批量执行shell命令

    [root@master ~]# cat a.py #!/usr/bin/python # -*- coding:UTF- -*- import subprocess def fun(): subpr ...

  5. 【JulyEdu-Python基础】第 6 课:高级面向对象

    使用@property添加属性和自定义属性 __slots__和property 方法和属性的动态绑定 使用__slots__限定class实例能添加的属性 __slots__仅对当前类实例起作用,对 ...

  6. 【神经网络与深度学习】GLog使用笔记

    环境: XPsp3 vs2005 glog-0.3.3 http://download.csdn.net/detail/chenguangxing3/6661667 编译: glog-0.3.3里面有 ...

  7. js继承的方式及其优缺点

    js继承方法 前因:ECMAScript不支持接口继承,只支持实现继承 一.原型链 概念:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针,让 ...

  8. 3的倍数 或运算构造x(牛客第四场)-- triples I

    题意: 给你一个数,希望你能用最少的3的倍数或运算成它,让你输出答案. 思路: 进制%3有规律,1.2.4.8.16%3是1.2.1.2.1 ... 利用这一点分情况取一些位合成一些数就是答案了. # ...

  9. Mysql8 root密码忘记了

    需要确定自己的mysql版本是否是8 [root@smonitor ~]# mysql --version mysql Ver 8.0.13 for Linux on x86_64 (MySQL Co ...

  10. Dasha and Photos CodeForces - 761F (前缀优化)

    大意: 给定n*m初始字符矩阵, 有k个新矩阵, 第$i$个矩阵是由初始矩阵区间赋值得到的, 求选择一个新矩阵, 使得其余新矩阵到它距离和最小. 字符集比较小, 可以考虑每次区间覆盖对每个字符的贡献. ...