这涉及"软件算法" https://stackoverflow.com/help/on-topic
我目前正在写一个单词计数字典程序。为了存储不同的字数,我使用二进制搜索三,以字为键,频率为值。
这是我的二进制搜索树类
public class BinarySearchTree<AnyKey extends Comparable<? super AnyKey>, AnyValue>
implements MyTreeMap<AnyKey, AnyValue>{
protected BinaryNode<AnyKey, AnyValue> root;
protected BinaryNode<AnyKey, AnyValue> insert(AnyKey x,
AnyValue y, BinaryNode<AnyKey, AnyValue> t ){
if( t == null )
t = new BinaryNode<AnyKey, AnyValue>(x, y );
else if( x.compareTo( t.element ) < 0 )
t.left = insert( x, y, t.left );
else if( x.compareTo( t.element ) > 0 )
t.right = insert( x, y, t.right );
else
throw new IllegalArgumentException( x.toString( ) );
return t;
}
这是我的节点类
class BinaryNode<AnyKey, AnyValue> {
BinaryNode( AnyKey theElement, AnyValue theValue ){
element = theElement;
value = theValue;
left = right = null;
}
AnyKey element;
AnyValue value;
BinaryNode<AnyKey, AnyValue> left;
BinaryNode<AnyKey, AnyValue> right;
}
我正在尝试在二进制搜索树中编写此方法
@Override
public void PrintMostFrequent(int n) {
}
它会根据频率打印出第n个最常用的单词。我知道如何在伪代码中执行此操作。
1。创建一个用于保存节点的集合
2。将树中的所有节点添加到此集合中
3。根据计数对集合进行排序
4。迭代排序的集合并打印出最常见的第n个。
这是解决此问题的最佳方法/编写此方法吗?我担心创建一个单独的集合可能过于昂贵,而且排序的计算成本也很高。
答案 0 :(得分:0)
你的方法描述也非常好。当你考虑需要在插入到树中的一个插入新单词时将是复杂的,这将采用O(logn)并且在最坏情况下在排序列表O(n)上然后再次搜索O(n)。
为了在搜索第n个频繁节点时获得更好的性能,插入一个方法将创建一个BST 但具有频率。因此,在两个树中插入新节点将采用O(logn)并搜索O(logn)。
在上面的方法中,您有数据冗余,即第二棵树将具有单词和频率。因此,为了避免你可以做的是在第二个BST中,只需将频率和一个引用放在第一个BST中的单词节点,你可以随时从一棵树跳到另一棵树。
答案 1 :(得分:0)
解决方案是:
TreeSet<Node> result
。if current > result.lowest() then result.pollFirst(); result.add(current)
这有限的空间成本,应该更快,因为大多数元素可以直接跳过。
但请注意,除非您正在处理大型数组并追踪此功能的速度,否则您的解决方案的简单性使其成为更好的选择。