Java程序在BST中查找第k个最小元素

标签 java binary-search-tree

我正在编写一个 Java 程序来查找 BST 中的第 k 个最小元素。

我已经浏览了有关堆栈溢出问题的其他一些帖子,并浏览了他们的解决方案,但我无法理解我的代码有什么问题。 如果有人可以请告诉我为什么我的程序不打印任何内容。

//Program to find the kth smallest element in the BST
public class KthSmallestElement {
static Node root;
//method to insert a key
Node insertRec(Node root, int key)
{
    //if the tree is empty
    if(root == null)
    {
       root = new Node(key);
       return root;
    }
    //otherwise recur down the tree
    else
    {
        if(key > root.key)
        {
            root.right = insertRec(root.right, key);
        }
        else
        {
            root.left = insertRec(root.left, key);
        }
        return root;
     }
}

//This method is for calling the insertRec() method
Node insert(int key)
    {
        root = insertRec(root, key);
        return root;
    }

//This method is for doing the inorder traversal of the tree
void kthSmallest(Node root, int k)
{
    int counter = 0;
    if(root == null)
        return;
   else
    {
             kthSmallest(root.left, k);
             counter++;

    if(counter == k)
        {
          System.out.println(root.key);
         }
        kthSmallest(root.right, k); 
    }
 }    

 //main method
public static void main(String[] args)
{
    KthSmallestElement tree = new KthSmallestElement();
    Node root = null;
    root = tree.insert(20);
    root =tree.insert(8);
    root =tree.insert(22);
    root =tree.insert(4);
    root= tree.insert(12);
    root =tree.insert(10);
    root =tree.insert(14);
    tree.kthSmallest(root, 3);
}

}

我的节点类如下:

//Class containing left and right child of current node and key value
public class Node {
int key;
Node left, right, parent;

//Constructor for the node
public Node(int item){
  key = item;
  left = right = parent= null;
}

}

它没有打印任何东西。这就是问题所在。 好吧,我不太擅长编程,所以请原谅我在这里问这样的问题。

最佳答案

您的计数器 k 从未更新过,并且 counter 具有方法范围,并且会在每次递归调用时被丢弃,从而导致问题。您需要创建一个在所有方法调用中保持一致的计数器:

int kthSmallest(Node root , int k){
    //empty root, don't change counter
    if(root == null)
        return k;
    else {
         //update counter - equivalent to k -= root.left.size()
         k = kthSmallest(root.left, k);

         if(k == 0) //kth element
         {
             System.out.println(root.key);
             return -1; //return some invalid counter
         }

         //currently visited node
         k--;

         //search right subtree
         return kthSmallest(root.right, k); 
    }
}

此代码使用 k 作为计数器,从 k 倒数到 0,并返回 k 变为 0 的节点。

您的代码不起作用,因为 counter 具有方法本地范围。这意味着 counter 的值仅对当前的 kthSmallest 调用有效。在下一次递归调用中,counter 将设置为 0 - 请注意,这是内存中的另一个 counter,而不是上一次调用的计数器 -因此你的代码无法达到 counter == k,除非 k == 1

对于这棵树:

                                   1
                                /     \
                               2       3

程序流程的描述如下所示,对于 k > 1:

//i'll apply IDs to uniquely identify each function-call and
// it's corresponding variables. the suffix #<Uppercase Letter>
// is used to identify a variable by corresponding method-call

kthElement(n , k): #A 
|   counter#A = 0 //initialize counter
|
|   kthElement(n.left , k): #B
|   |   counter#B = 0
|   |
|   |   kthElement(n.left.left , k): #C
|   |   |   counter#C = 0
|   |   |   n.left.left == null -> return from #D
|   |
|   |   counter#B++ -> counter#B = 1
|   |
|   |   counter#B != k -> don't print
|   |
|   |   kthElement(n.left.right , k): #D
|   |   |   counter#D = 0
|   |   |   n.left.right == null -> return from #D
|   |
|   |   end of method -> implicit return from #B
|   
|   counter#A++ -> counter#A = 1
|   ...
...

请注意 kthElement 的每次调用如何创建自己的计数器,每个节点仅递增一次。

关于Java程序在BST中查找第k个最小元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37165945/

相关文章:

python - 二叉搜索树遍历

java - 计算二叉搜索树的深度?

Java:快速淡入淡出 javax.sound.sampled.Clip 的增益

java - 内联网应用程序的签名小程序

java - css img :hover working, img:active 不是

c - 访问返回的二叉树的内容时出现问题

c++ - 即使不执行 return,非 void 函数也能正常工作

c++ - 二叉搜索树中序遍历递归函数不能正常工作

java - 反编译的.class文件,字节码版本: 51. 0 (java 7)

java - 为什么我们允许在 java 中有一个 final main 方法?