题目描述:

/**
* 给定一棵二叉搜索树,请找出其中的第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. mysql的基本操作命令

    1,数据库操作: create database 数据库名 例:create database test; 亦或 create database test charset=utf8; 相关操作: 显示 ...

  2. mac 安装photoshop + 破解

    项目开发中毫无疑问会用到图片,一般情况都是UI将图片切好的,只是,有时候项目中少了一张图片或者是改变图片的尺寸之类的问题,这里我们就不需要每次都找UI要图片了,作为程序员这些基础工具的使用,咱们还是要 ...

  3. python django项目创建及前期准备(使用pycharm)

    一.创建django项目 1.打开pycharm软件 2.点击菜单栏 File-->New Project,弹出如下对话框,如下图设置 二.基本配置 1.静态文件目录配置(用于客户端访问后台服务 ...

  4. ES5与ES6常用语法教程之 ②解构语法糖、声明变量异同

    js常用语法系列教程如下 es5与es6常用语法教程(1) es5与es6常用语法教程(2) es5与es6常用语法教程(3) es5与es6常用语法教程(4) es5与es6常用语法教程(5) es ...

  5. CTF—攻防练习之HTTP—命令执行漏洞

    渗透环境: 主机:192.168.32.152 靶机:192.168.32.1 命令执行漏洞 命令执行漏洞概念:当应用需要调用一些外部程序去处理内容的情况下,就会用到一些执行系统命令的函数.如PHP中 ...

  6. PYTHON TDD学习(一)-->Python 3.4版本环境安装Django及其启动

    1.安装Python3.4版本,原因:3.4及其以后版本默认自带pip工具,非常好用 2.django 安装命令(c:\Python34\Scripts):pip install django 3.s ...

  7. idea关闭自动更新

    如何关闭idea的自动更新? File-Setting-Appearance&Beha-System Setting-Updates 取消勾选Automatically check updat ...

  8. Spring MVC 根容器和子容器

    整合 spring mvc 根容器和子容器 public class TestWebInitializer extends AbstractAnnotationConfigDispatcherServ ...

  9. 【Linux开发】linux设备驱动归纳总结(四):1.进程管理的相关概念

    linux设备驱动归纳总结(四):1.进程管理的相关概念 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  10. 3 基于梯度的攻击——MIM

    MIM攻击原论文地址——https://arxiv.org/pdf/1710.06081.pdf 1.MIM攻击的原理 MIM攻击全称是 Momentum Iterative Method,其实这也是 ...