在BST中查找第k个最小值

时间:2011-05-03 01:17:55

标签: c binary-search-tree

这是我必须在二叉搜索树中找到第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个最小元素。

3 个答案:

答案 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)