所以我有一个BST,它的元素是TreeNode类型。每个TreeNode对象都包含一个WordFreq对象,该对象由一个名为word的String变量和一个名为freq的整数变量组成。元素是我的程序从文件中读取的单词,因此变量“word”是String,变量freq表示单词在文本中出现的频率。所以我想要做的是通过整个BST并找到具有最大频率(最大频率)的TreeNode。我尝试了很多方法,但它似乎没有用。单词按字母顺序排在树上,不按频率排序。这是我的方法:
public WordFreq getMaximumFrequency() {
return getMaximumFrequencyR(head, 1);
}
public WordFreq getMaximumFrequencyR(TreeNode h, int i) {
WordFreq temp = h.getWordFreq();
if (h.getWordFreq().getFreq() > getMeanFrequency()) { //line 3
if (h.l != null) {
if (h.getWordFreq().getFreq() >= i){
i = h.getWordFreq().getFreq();
temp = h.getWordFreq();
getMaximumFrequencyR(h.l, i);
}
}
if (h.r != null) {
if (h.getWordFreq().getFreq() >= i){
i = h.getWordFreq().getFreq();
temp = h.getWordFreq();
getMaximumFrequencyR(h.r, i);
}
}
}
else {
if (h.l != null) {
getMaximumFrequencyR(h.l, i);
}
if (h.r != null) {
getMaximumFrequencyR(h.r, i);
}
}
return temp;
}
getMeanFrequency()是一种返回平均频率的方法。第3行的比较是有意义的,因为当一个词的频率大于树的平均频率时,需要(对于我的分配)要插入根。这意味着我正在寻找的最大频率不能位于树的底部。 (语言是Java) 你知道我怎么能做这个工作吗?
这里有一些有用的方法信息,以便更好地理解我的代码: class TreeNode:
public class TreeNode {
private WordFreq wf;
private TreeNode l, r;
private int N;
private TreeNode head;
public TreeNode() {
head = null;
l = null;
r = null;
}
public TreeNode(WordFreq wf) {
this.wf =wf;
l = null;
r = null;
N = 0;
}
public void incrSubtree(TreeNode tn) {
tn.N++;
}
public void decrSubtree(TreeNode tn) {
tn.N--;
}
public WordFreq getWordFreq() {
return wf;
}
}
类WordFreq:
public class WordFreq {
private String word;
private int freq;
public WordFreq(String word) {
this.word = word;
freq=1;
}
public String key() {
return this.word;
}
public void freqIncrease(WordFreq w) {
w.freq++;
}
public String toString() {
return "The word " + key() + " has frequency " + getFreq() + ".";
}
public int getFreq() {
return freq;
}
}
答案 0 :(得分:0)
您想要的算法的伪代码是:
maxFrequency(NULL) = 0
maxFrequency(Node) = max(frequency(Node.value),maxFrequency(Node.right),maxFrequency(Node.Left));
将此伪代码转换为java应该不难。
请注意,这并未利用在根处插入具有高于平均频率的节点的事实。我不认为实现一种算法很容易。
答案 1 :(得分:0)
如果你需要对树进行详尽的搜索(即最高频率的词可能在任何地方),那么我相信这就变得相对容易了。
但是,首先我建议您不要在l
中将r
和TreeNode
成员设置为空。相反,我建议你有一个私有静态EMPTY
TreeNode,它会覆盖适当的方法来播放null的一部分 - 比如将字频率恢复为0.有很多理由这样做,但不是列出它我建议你谷歌吧!我会假设你已经在下面的代码中完成了这项工作,因为它使事情变得更加整洁。
添加TreeNode
方法:
public TreeNode maxFrequency() {
return Arrays.asList(this, l.maxFrequenc(), r.maxFrequency()).stream()
.max((tn1, tn2) -> tn1.wf.compareTo(tn2.wf))
.orElse(EMPTY);
}
让我解释一下,如果您对Java 8流没有经验,这是如何工作的。 Arrays.asList
行从左侧和右侧创建当前节点和最大词频节点的列表,然后将它们转换为流。 max
语句使用compareTo
方法找到具有最高单词频率的语句(您需要将其添加到WordFrequency
类)。这将返回可能不存在的Optional<TreeNode>
,因此如果没有最大值,orElse
语句将返回EMPTY。
最后,您需要覆盖maxFrequency
TreeNode中的EMPTY
方法,只返回this
以避免无限递归。