二叉搜索树:如何比较其元素的变量值?

时间:2015-01-16 00:38:25

标签: java

所以我有一个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;
}

}

2 个答案:

答案 0 :(得分:0)

您想要的算法的伪代码是:

maxFrequency(NULL) = 0
maxFrequency(Node) =  max(frequency(Node.value),maxFrequency(Node.right),maxFrequency(Node.Left));

将此伪代码转换为java应该不难。

请注意,这并未利用在根处插入具有高于平均频率的节点的事实。我不认为实现一种算法很容易。

答案 1 :(得分:0)

如果你需要对树进行详尽的搜索(即最高频率的词可能在任何地方),那么我相信这就变得相对容易了。

但是,首先我建议您不要在l中将rTreeNode成员设置为空。相反,我建议你有一个私有静态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以避免无限递归。