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

Performance 在给定的平衡二叉搜索树中查找最小(或最大)k个元素,performance,algorithm,binary-search-tree,Performance,Algorithm,Binary Search Tree,给定一个带有整数节点的平衡二叉搜索树,我需要编写一个算法来查找最小的k个元素,并将它们存储在链表或数组中。棘手的部分是,这种算法需要在O(k+log(n))中运行,其中n是树中的元素数。我只有一个运行O(k*log(n))的算法,它使用秩函数。因此,我的问题是如何实现所需的性能 我已经编写了一段代码来执行这种算法,但我不知道它是否在O(k+log(n))下运行: (大小函数是具有给定子树的节点数。) //在树中查找k个最小元素 公共Iterable kSmallest(int k){ Linke

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

我已经编写了一段代码来执行这种算法,但我不知道它是否在O(k+log(n))下运行:

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

//在树中查找k个最小元素
公共Iterable kSmallest(int k){
LinkedList keys=新建LinkedList();
k最小(k,根,键);
返回键;
}
//在节点给定的子树中找到k个最小元素,并将它们添加到键中
私有void kSmallest(int k、节点节点、LinkedList键){
如果(k=k)k最小(k,node.left,keys);
否则{
key.add(node.key);
kSmallest(k-1,node.left,keys);
kSmallest(k-1-大小(node.left)、node.right、键);
}
}
否则{
key.add(node.key);
kSmallest(k-1,node.right,keys);
}
}

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

代码:

int k=nodesRequired;
int A[]=新的int[k];
int number_of_节点=0;
无效遍历树(树*l){
if(左节点的数量);
处理物料(l->物料);
遍历树(左->右);
}
}
作废流程\项目(项目){
A.推动(项目);
++节点的数量;
}

按顺序遍历树,并在遍历k个节点后停止。遍历需要O(k)个时间,但如果也要构造二叉树,则需要O(n*log(n)+k)个时间。在这方面帮不上忙..如果从根开始遍历需要O(logn+k)个时间,因为在找到第一个元素之前有log(n)个步骤。我有一个原型可以工作,但不知道它的性能。你能分析它吗?这需要O(logn+k)时间,因为在处理第一个项目之前有O(logn)个步骤。还有一个bug(
==k
应该是
@Anonymous,谢谢,你的意思是>=k?我认为它是正确的,因为所有测试输出都是正确的。@Anonymous感谢对更改所做的更正。你能帮我理解时间复杂度分析吗?初始化数组a和O(logn)需要O(k)时间确定BST最小值的时间到了。我很难理解如何计算识别剩余k-1元素并将其推到A所需的时间。
// 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);
    }
}
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;
 }