题目描述:

/**
* 给定一棵二叉搜索树,请找出其中的第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. openstack共享组件--memcache缓存(2)

    一.缓存系统 一.静态web页面: 1.在静态Web程序中,客户端使用Web浏览器(IE.FireFox等)经过网络(Network)连接到服务器上,使用HTTP协议发起一个请求(Request),告 ...

  2. Spring学习之==>IoC

    一.概述 Spring的三大核心思想:IoC(控制反转),DI(依赖注入),AOP(面向切面编程).本问讲着重介绍一下控制反转. 何谓控制反转:Spring 通过一种称作控制反转(IoC)的技术促进了 ...

  3. 2019.12.05【ABAP随笔】 分组循环(LOOP AT Group) / REDUCE

    ABAP 7.40新语法 LOOP AT Group 和 REDUCE *LOOP AT itab result [cond] GROUP BY key ( key1 = dobj1 key2 = d ...

  4. 002. Add Two Numbers

    题目链接:https://leetcode.com/problems/add-two-numbers/description/ Example: Input: (2 -> 4 -> 3) ...

  5. shaderToy学习篇

    觉得shadertoy上的一些网友的作品写得很好,加上自己对glsl一些内置函数,内置变量不是很熟悉,于是决定开始学习一下上面一些大佬的代码. 今天的案例是这个: 附上shaderToy的地址:htt ...

  6. java8:(Lambda 表达式,Supplier,@FunctionalInterface,foreach(),Optional,Stream().collect,双冒号,joining,partitioningBy分区,collectingAndThen,filter())

    1.Lambda 表达式: 引导:http://www.cnblogs.com/yulinfeng/p/8452379.html DEMO1: List<String> names1 = ...

  7. 如何在robotframework基础上使用数据驱动测试

    一.写在前面 robotframework是很好用的关键字驱动测试框架,但是在实际工作中也有些地方使用不便,比如在我们设计参数校验测试case时,往往只是想修改校验参数类型而不得不做大量复制粘贴操作, ...

  8. monkey详解

    Monkey是Android系统自带的一个命令行工具,用户主要是通过adb命令来启动Monkey,Monkey在运行时,会根据命令行参数的配置,生成伪随机事件流,并在Android设备上执行对应的测试 ...

  9. VS2008新增文件没有模板

    可能是我安装的过程中发神经没有选中选项什么的,打开来想建个项目发现一个模板都没有,那就很尴尬了,作为对开发工具极度依赖的人,这真的难受... 在网上找到别人的办法 开始 –> 程序 –> ...

  10. [转帖]ASML发布Q1季度财报 营收22.3亿欧元,EUV光刻机下半年产能大增 ...

    ASML发布Q1季度财报营收22.3亿欧元,EUV光刻机下半年产能大增 ... 孟宪瑞发布于2019-4-18 10:32 https://www.expreview.com/67969.html 一 ...