请不要理会我的英语水平,因为我不是母语。 我正在寻找在BST中找到第k个最小元素的最佳方法,我想到了将树追加到列表并遍历该列表的方法,但是这花费了太多时间O(n) 我还考虑过从树中删除元素,然后找到最小的元素,但这也需要更多时间。 解决此问题的最佳算法是什么? 由于scheme是一种功能编程语言,因此解决方案必须是递归的。我试图寻找答案,但是大多数C或Java答案都将使用某种迭代格式。 谢谢您的帮助, 我的功能应该看起来像 (定义(第k个最小的T k) ...)
答案 0 :(得分:0)
如果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)
祝你好运
答案 1 :(得分:0)
如果左侧子树的大小大于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)