在BST中找到第k个最小数字

时间:2015-09-08 18:34:54

标签: java binary-search-tree

这是一个递归的解决方案: -

 private static int INDEX = 0;

 public static void findKthSmallest(Node node) { 

  if (node == null) {
   System.out.println("Tree is empty!!");
   return;
  } 


  if (node.left != null) {
      findKthSmallesRecursive(node.left);
  }

  ++INDEX;

  if (K == INDEX) {
   System.out.println("Kth Smallest Node Value: " + node.data);
   return;
  }  

  if (node.right != null) {
      findKthSmallesRecursive(node.right);
  }

 }

如果树是: -

   10
   /
  5
 /
2

假设k是2 第二个最小的元素是= 5.

第一次递归通话:findkthSmallest(10)调用findkthsmallest (5)然后调用findkthsmallest (2)。现在我很困惑如何从这一点处理递归调用。并给出所需的输出。代码运行正常并给出预期的结果。

3 个答案:

答案 0 :(得分:0)

看起来你的意思是BST中的K = Level并将它们传递给方法。 当满足(2 == INDEX)时,递归停止,返回语句打印所需的结果。 它回溯到它的调用者,但由于没有为返回值定义操作,它只是回溯直到它达到触发递归的原始级别

答案 1 :(得分:0)

代码以顺序遍历树;即它首先是左边的孩子,然后是根,然后是右边的孩子。

在访问特定节点的左子树之后,它会递增索引并检查它是否等于k;如果是,则它是目标节点;

由于特定节点左子树中的所有节点总是小于节点;并且在该特定父节点之前处理整个左子树;并且在处理节点时递增索引变量;所以直到第K个最小节点,索引变量将保持正确的结果,但是一旦你得到第k个最小节点,它将跳过其右子树中存在的所有元素,控件将被传递给父节点将继续处理其右子树,而不知道子树中跳过的子树中存在的节点数。

为了使它更简单,让我们使用你提到的例子:

Lets define the whole code as a 4 step process:

a. Check the left child and process if it exists.

b. Increment the value of index.

c. Check if the index is equal to k and return if yes.

d. Check the right child and process if it exists.




  We begin with root node i.e. 10:

    1.a. findKthSmallest(10) calls findKthSmallest(5) as its left is not null.

    2.a. findKthSmallest(5) calls findKthSmallest(2) as its left is not null.

    3.a. findKthSmallest(2) cant call its left as it does not have any left child.

    3.b. Index is incremented for Node 2 . Now index=1.

    3.c. Is index==k ?? No, so proceed to step d.

    3.d. findKthSmallest(2) cant call its right as it does not have any right child.

    2.b. Index is incremented for node 5. Now index=2.

    2.c. Is index==k ?? Yes, So don't run step d and return.

    1.b. Index is incremented for Node 2 . Now index=3.

    1.c. Is index==k ?? No, so proceed to step d.

    1.d. findKthSmallest(2) cant call its right as it does not have any right child.

答案 2 :(得分:0)

与所有递归*一样,调用堆栈包含操作的控件,因为递归调用开始返回 - 程序控制返回到你的current_node指针设置为你在递归之前检查的父项的位置调用

(* All recursion, unless there's tail-call optimization going on, in which case it is just a loop).

当你递归或者自己调用函数时,参数每次都会改变。在遍历二叉搜索树的情况下,每个递归调用都将二叉树的不同节点作为参数。

初始函数调用被赋予二叉搜索树的头节点。该节点有一个值。如果该值等于您要查找的值,则找到它并返回true。如果它更大,那么你知道,如果你有机会找到你的值,它将在树的左边部分,所以你递归调用相同的函数,将左子节点作为新参数传递。否则(节点的值小于目标值)使用正确的子节点。如果您想使用子节点递归调用但没有子节点,那么您已经到达搜索的末尾并且可以返回false。

BST示例:

enter image description here

<强> 说明: "binary search tree" (BST) or "ordered binary tree"是一种二叉树,其中节点按顺序排列:对于每个节点,其left subtree中的所有元素都是less-or-equal to the node (<=),其右子树中的所有元素都更大比node (>)。上面显示的树是二叉搜索树 - "root" node is a 5及其left subtree nodes (1, 3, 4) are <= 5及其right subtree nodes (6, 9) are > 5。递归地,每个子树还必须遵守二叉搜索树约束:在(1, 3, 4) subtree中,3是根,1 <= 3 and 4 > 3。注意问题中的确切措辞 - “二叉搜索树”与“二叉树”不同。

树底部边缘的节点有空子树,称为“叶子”节点(1,4,6),而其他节点是“内部”节点(3,5,9)。

有关详细信息,您可以关注BST