面试题 63:二叉搜索树的第k个结点

题目:给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 (见下面的图1) 中,按结点数值大小顺序第三个结点的值为4。

图1:一个有7个结点的二叉搜索树,如果按结点数值大小顺序输出,则第3个结点的值是4

提交网址: http://www.nowcoder.com/practice/ef068f602dde4d28aab2b210e859150a?tpId=13&tqId=11215

分析:

对于二叉搜索树BST,在树中任取一棵子树,其节点值都满足:左结点的值 < 父节点的值 < 右结点的值,故如果按照中序遍历的顺序遍历一棵二叉搜索树BST,遍历序列的数值是递增序的。只需要用中序遍历算法遍历一棵二叉搜索树BST,就可以找出它的第k大结点。非递归中序遍历加上计数器即可解决。

  1.        6
  2.      /   \
  3.     3      8
  4.   /  \    /  \
  5.  2   5  7    9

非递归实现 AC代码:

  1. #include<cstdio>
  2. #include<vector>
  3. #include<stack>
  4. using namespace std;
  5. struct TreeNode{
  6. int val;
  7. struct TreeNode *left;
  8. struct TreeNode *right;
  9. TreeNode(int x) :
  10. val(x), left(NULL), right(NULL) {
  11. }
  12. };
  13. class Solution {
  14. public:
  15. TreeNode* KthNode(TreeNode* pRoot, unsigned int k)
  16. {
  17. TreeNode *p=pRoot;
  18. TreeNode *resNode;
  19. if(p==NULL || k==0) return NULL;
  20. stack<TreeNode *> st;
  21. unsigned int count=0;
  22. while(!st.empty() || p != NULL)
  23. {
  24. if(p != NULL)
  25. {
  26. st.push(p);
  27. p=p->left;
  28. }
  29. if(p == NULL)
  30. {
  31. p=st.top(); // 取当前节点
  32. count++;
  33. if(count==k) resNode=p;
  34. st.pop();
  35. p=p->right;
  36. }
  37. }
  38. return resNode;
  39. }
  40. };
  41. // 以下为测试
  42. int main()
  43. {
  44. Solution sol;
  45. TreeNode* root = new TreeNode(6);
  46. root->left = new TreeNode(3);
  47. root->left->left = new TreeNode(2);
  48. root->left->right = new TreeNode(5);
  49. root->right = new TreeNode(8);
  50. root->right->left = new TreeNode(7);
  51. root->right->right = new TreeNode(9);
  52. TreeNode* p=sol.KthNode(root, 3);
  53. printf("The value of Kth Node is: %d\n", p->val);
  54. return 0;
  55. }

而提交同样作用的代码到牛客网OJ却报错了: control may reach end of non-void function [-Werror,-Wreturn-type, 本地在Visual Studio和Dev C++上都测试通过的...

意思好像是没有在函数最外层写统一的返回值,改了就AC了...

  1. class Solution {
  2. public:
  3. TreeNode* KthNode(TreeNode* pRoot, unsigned int k)
  4. {
  5. TreeNode *p=pRoot;
  6. if(p==NULL || k==0) return NULL;
  7. stack<TreeNode *> st;
  8. unsigned int count=0;
  9. while(!st.empty() || p != NULL)
  10. {
  11. if(p != NULL)
  12. {
  13. st.push(p);
  14. p=p->left;
  15. }
  16. if(p == NULL)
  17. {
  18. p=st.top(); // 取当前节点
  19. count++;
  20. if(count==k) return p;
  21. st.pop();
  22. p=p->right;
  23. }
  24. }
  25. }
  26. };

C++版 - 剑指offer 面试题63:二叉搜索树的第k个结点(二叉树中序遍历的应用) 题解的更多相关文章

  1. 【剑指Offer】62、二叉搜索树的第k个结点

      题目描述:   给定一棵二叉搜索树,请找出其中的第k小的结点.例如(5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4.   解题思路:   本题实际上比较简单,主要还是考察对 ...

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

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

  3. 剑指Offer:面试题27——二叉搜索树与双向链表(java实现)

    问题描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路: 将树分为三部分:左子树,根结点,右子树. 1.我们要把根结点与左 ...

  4. 剑指Offer:面试题24——二叉搜索树的后序遍历序列(java实现)

    问题描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. 思路: 1.首先后序遍历的结果是[(左子 ...

  5. 剑指offer 面试题36.二叉搜索树与双向链表

    中序递归,一个pre节点记录前一个节点 /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; Tre ...

  6. 剑指offer(62)二叉搜索树的第K个节点

    题目描述 给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8)    中,按结点数值大小顺序第三小结点的值为4. 题目分析 首先,我们可以先画图.画完图后我们要想办法从 ...

  7. 剑指Offer - 九度1503 - 二叉搜索树与双向链表

    剑指Offer - 九度1503 - 二叉搜索树与双向链表2014-02-05 23:39 题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树 ...

  8. 剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列

    剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列2013-11-23 03:16 题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出 ...

  9. 剑指offer(23)二叉搜索树的后序遍历序列

    题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 题目分析 1.后续遍历我们可以知道,最右边的是根节 ...

随机推荐

  1. VS 在创建C#类时添加文件描述

    在新建一个C#类时,为了描述该类的功能.以及文件建立的相关信息,并保护自己的版权要在文件的开头添加一些信息.如下: /***************************************** ...

  2. Springboot+Mybatis+Thymeleaf

    工具Eclipse 2018 Maven 配置 ThymeLeaf 安装:  https://blog.csdn.net/xingqibaing/article/details/82787164 sp ...

  3. day33 锁和队列

    队列 #put 和  get #__author : 'liuyang' #date : 2019/4/16 0016 上午 11:32 # 多进程之间的数据是隔离的 # 进程之间的数据交互 # 是可 ...

  4. python 基础———— 字符串常用的调用 (图2)

    1.  replace 2.  join 3.split 4 rsplit 5. strip : 去除字符串左右两边特定(指定)的字符 7. rstrip  :  去除右边特定(指定)的字符 8. l ...

  5. P3806 【模板】点分治1

    一道淀粉质的模版题,开始是暴力 #include <bits/stdc++.h> #define up(i,l,r) for(register int i = (l); i <= ( ...

  6. Spring学习-01

    一.Srping 一个轻量级DI.IOC.AOP的容器框架 DI:依赖注入 IOC:控制反转 AOP:面向切面 二.构造器注入 Constructor-arg 属性:index/name/type/r ...

  7. .net读取excel数据到DataSet中

    Dim objExcelFile As Excel.Application Dim objWorkBook As Excel.Workbook Dim objSheet As Excel.Worksh ...

  8. 关于PHP读取HTTP头的部分

    本文转载自https://my.oschina.net/luoczi/blog/86608 1.关于PHP读取HTTP头的方法 $_SERVER['PHP_SELF'] #当前正在执行脚本的文件名,与 ...

  9. Promise(一)

    每个Promise对象就是一个值的代理,这个值在Promise创建时可以是未知的.Promise对象允许你为异步事件的成功操作和失败操作分别绑定对应的处理方法,让异步方法可以像同步方法那样返回值,但不 ...

  10. Linux基础操作命令

    一.系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 – (SMBIO ...