【问题标题】:Finding the kth smallest value in a BST在 BST 中找到第 k 个最小值
【发布时间】:2011-05-03 13:01:16
【问题描述】:

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

【问题讨论】:

    标签: c binary-search-tree


    【解决方案1】:

    BST 是排序的二叉树,按顺序遍历(左子树、当前节点、右子树)将给出排序后的节点值。要找到第 k 个最小的节点,只需使用计数器进行中序遍历。计数器从 0 开始,每次遍历一个节点,就加一,当达到 k 时,该节点是第 k 个最小的。

    【讨论】:

    【解决方案2】:

    如果您有每个子树的大小,则无需将数据读入数组(或以其他方式遍历树)并向上计数,这是可行的。如果您不方便保留尺寸信息,则需要一个辅助函数来计算尺寸。

    基本思路,弄清楚当前节点的索引是什么。如果小于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,所以当前节点必须是第 2 个。

    假设我们要找到第 4 个 (k = 4)。
    从 3 开始,左子树的大小为 3。
    它小于 l 所以将新的 k 调整为 0 (k' = 4 - (3 + 1)) 并移动到右子树。
    从 6 开始,左子树的大小为 2。
    它大于 k' (0) 所以移动到左子树。
    左子树的大小为0。
    k' 也是 0,所以当前节点必须是第 4 个。

    你明白了。

    【讨论】:

      【解决方案3】:

      这应该可行:

      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)

      【讨论】:

        猜你喜欢
        • 2021-01-06
        • 1970-01-01
        • 1970-01-01
        • 2020-03-02
        • 1970-01-01
        • 2020-03-28
        • 1970-01-01
        • 1970-01-01
        • 2015-01-15
        相关资源
        最近更新 更多