Java 寻找 BST 中第 k 个最小元素的程序
Java program to find the kth smallest element in a BST
我正在编写一个 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如下:
//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;
}
}
这不是打印 anything.That 的问题。
好吧,我不太会编程所以请原谅我在这里问这样的问题。
您的计数器 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 和 returns 节点递减计数,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
的每次调用如何创建它自己的 counter
,每个节点仅递增一次。
我正在编写一个 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如下:
//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;
}
}
这不是打印 anything.That 的问题。 好吧,我不太会编程所以请原谅我在这里问这样的问题。
您的计数器 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 和 returns 节点递减计数,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
的每次调用如何创建它自己的 counter
,每个节点仅递增一次。