【问题标题】:Kth smallest element in a BST(scheme)BST(方案)中的第 K 个最小元素
【发布时间】:2020-03-02 08:07:59
【问题描述】:

请忽略我蹩脚的英语,因为我不是母语人士。 我正在寻找在 BST 中找到第 k 个最小元素的最佳方法,我想过将树附加到列表并遍历该列表之类的方法,但这需要太多时间 O(n) 我还考虑过从树中删除元素,然后找到最小的元素,但这也需要更多时间。 解决这个问题的最佳算法是什么? 由于方案是一种函数式编程语言,因此解决方案必须是递归的。我试图寻找答案,但 C 或 Java 中的大多数答案都会使用某种迭代格式。 谢谢您的帮助, 我的功能应该看起来像 (定义 (kth-smallest T k) ...)

【问题讨论】:

  • 为了比 O(n) 更好地做到这一点,它需要是一个平衡树,并且您需要能够在不搜索的情况下计算子树的大小。您没有显示任何代码,所以我不知道是否可以使用您的数据结构。
  • 我的数据结构很简单。将树定义为一个值的列表,左右。我看到了你的想法,但我不知道如何实现它。但我想这是正确的方法

标签: algorithm scheme binary-search-tree racket


【解决方案1】:

如果 BST 是有序且平衡的,则不是最左边的叶子是最低值。那么第 n 个最小值将是您在按顺序树遍历中迭代的第 n 个值。

因此在平衡树中找到最低的第 k 个值介于 O(log n) 和 O(2n) 之间。 O(n) 就是这样。

我的实现将创建一个帮助器,它需要一个延续以及k 和树。默认延续可以是(lambda (v) #f),因此如果你想要一个 10 节点树中的第 30 个最小的,它会调用它,你会得到#f。找到最深节点的第二个节点 k 为零,而不是调用它评估为当前节点值的延续。

如果你要删除最小值 k 次,你会有 O(k * log n) ~ O(n log n) > O(n)

祝你好运

【讨论】:

    【解决方案2】:

    如果左子树的大小大于 k,我们查看左子树,如果它更小,我们使用新的 k 查看右子树:k - size-of-left- subtree - 1,否则(在相等的情况下)我们返回当前节点的值。这是在 O(lg n) 时间内执行的。

    #lang racket
    
    (struct no-info ())
    (define NONE (no-info))
    
    ; [BST X] is one of:
    ; - (node NONE NONE NONE 0)
    ; - (node BST  BST  X    Number)
    
    (struct node [left right val size])
    (define leaf (node NONE NONE NONE 0))
    
    ; examples
    (define lt (node (node (node leaf leaf 10 1) (node leaf leaf 24 1) 15 3) leaf 29 4))
    (define rt (node (node leaf leaf 77 1) (node leaf (node leaf leaf 99 1) 95 2) 89 4))
    (define t (node lt rt 63 9))
    
    ;           63
    ;          /  \
    ;        29    89
    ;       /     /  \
    ;      15    77  95
    ;    /   \         \ 
    ;  10     24       99
    
    ; node val: 10 15 24 29 63 77 89 95 99
    ; rank:     1  2  3  4  5  6  7  8  9
    
    ; kth-smallest : BST -> X
    ; the value of the `k`th smallest node in `t`
    (define (kth-smallest t k)
      (define (kth-smallest-h t k)
        (cond [(equal? (node-size t) 1) (node-val t)]
              [else (let ([s (node-size (node-left t))])
                      (cond [(> s k) (kth-smallest-h (node-left t) k)]
                            [(< s k) (kth-smallest-h (node-right t) (sub1 (- k s)))]
                            [else (node-val t)]))]))
      (if (or (<= k 0) (> k (node-size t)))
          (error "k out of range")
          (kth-smallest-h t (sub1 k))))
    
    
    (map (λ (x) (kth-smallest t x)) '(1 2 3 4 5 6 7 8 9))
    ; => '(10 15 24 29 63 77 89 95 99)
    
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-06
      • 1970-01-01
      相关资源
      最近更新 更多