在给定的平衡二叉搜索树中查找最小(或最大)k元素

时间:2014-10-20 04:18:21

标签: performance algorithm binary-search-tree

给定具有整数节点的平衡二叉搜索树,我需要编写一个算法来查找最小的k个元素并将它们存储在链表或数组中。棘手的部分是,需要这样的算法在O(k + log(n))中运行,其中n是树中元素的数量。我只有一个运行O(k * log(n))的算法,它使用秩函数。所以我的问题是如何达到所需的性能?

我编写了一个执行此类算法的代码,但我不知道它是否在O(k + log(n))运行:

(size函数是具有给定子树的节点数。)

// find k smallest elements in the tree
public Iterable<Key> kSmallest(int k) {
    LinkedList<Key> keys = new LinkedList<Key>();
    kSmallest(k, root, keys);
    return keys;
}

// find k smallest elements in the subtree given by node and add them to keys
private void kSmallest(int k, Node node, LinkedList<Key> keys) {
    if (k <= 0 || node == null) return;
    if (node.left != null) {
        if (size(node.left) >= k) kSmallest(k, node.left, keys);
        else {
            keys.add(node.key);
            kSmallest(k - 1, node.left, keys);
            kSmallest(k - 1 - size(node.left), node.right, keys);
        }
    }
    else {
        keys.add(node.key);
        kSmallest(k - 1, node.right, keys);
    }
}

1 个答案:

答案 0 :(得分:3)

只需要进行顺序遍历并在经过k个节点时停止。 这将在O(k + log(n))时间内运行。

代码:

int k = nodesRequired;
int A[] = new int[k];
int number_of_nodes=0;
void traverse_tree(tree *l){
    if (number_of_nodes<k) {
        traverse_tree(l->left);
        process_item(l->item);
        traverse_tree(l->right);
    }
 }

 void process_item(item){
     A.push(item);
     ++number_of_nodes;
 }