这是我必须在二叉搜索树中找到第k个最小值:
struct treeNode
{
int data;
struct treeNode *left, *right:
};
int rank(stuct treeNode* ptr, int k)
{
if(node == NULL)
return root;
while(ptr->left != NULL) {
ptr = ptr->left;
return rank(ptr->left)
}
}
这显然不正确。如果没有提供解决方案,有人可以指导我如何解决这个问题吗?我无法弄清楚如何在BST中找到第k个最小元素。
答案 0 :(得分:5)
BST是一个已排序的二叉树,有序遍历(左子树,当前节点,右子树)将给出已排序的节点值。要查找第k个最小节点,只需使用计数器进行有序遍历。计数器从0开始,每当遍历一个节点时,将其增加1,当它达到k时,节点是第k个最小的节点。
答案 1 :(得分:1)
如果你有每个子树的大小,这可以是可行的,而不必将数据读入数组(或以其他方式遍历树)并向上计数。如果你不方便保持大小信息,你需要一个辅助函数来计算大小。
基本思路,弄清楚当前节点的索引是什么。如果小于k,则需要搜索左子树。如果它大于k,则搜索右侧偏移从左侧和当前计数的节点。请注意,这与搜索常规BST基本相同,除非这次我们按索引而不是数据进行搜索。一些伪代码:
if size of left subtree is equal to k:
// the current node is kth
return data of current node
else if size of left subtree is greater than k:
// the kth node is on the left
repeat on the left subtree
else if size of left subtree is less than k:
// the kth node is on the right
reduce k by the size of the left subtree + 1 // need to find the (k')th node on the right subtree
repeat on the right subtree
为了说明,请考虑带有标记索引的树(甚至不要担心数据,因为它在搜索中不重要):
3
/ \
2 6
/ / \
0 4 7
\ \
1 5
假设我们想要找到第二个(k = 2)
从3开始,左子树的大小为3
它大于k所以向左子树移动。
左子树的大小为2.
k也是2,因此当前节点必须是第二个。
假设我们想要找到第4个(k = 4)
从3开始,左子树的大小为3
它小于l所以将新k调整为0(k'= 4 - (3 + 1))并移动到右子树。
从6开始,左子树的大小为2
它大于k'(0)所以向左子树移动。
左子树的大小为0
k'也为0,因此当前节点必须是第4个。
你明白了。
答案 2 :(得分:0)
这应该有效:
int rank(struct treeNode* n,int k,int* chk)
{
if(!n) return -1;
int _chk = 0;
if(!chk) chk = &_chk;
int t = rank(n->left,k,chk);
if(t>=0) return t;
if(++*chk > k) return n->data;
int t = rank(n->right,k,chk);
if(t>=0) return t;
return -1;
}
拨打rank(root,k,0)