简体   繁体   English

Binary Search Trees:如何比较变量元素的值?

[英]Binary Search Trees : how can I compare variable's values of its elements?

So I have a BST and its elements are type TreeNode. 所以我有一个BST,它的元素是TreeNode类型。 Each TreeNode object includes a WordFreq object which consists of a String variable called word, and an integer variable called freq. 每个TreeNode对象都包含一个WordFreq对象,该对象由一个名为word的String变量和一个名为freq的整数变量组成。 The elements are words that my program reads from a file, so the variable "word" is that String, and variable freq represent the frequency that the word appears in the text. 元素是我的程序从文件中读取的单词,因此变量“ word”是字符串,变量freq表示单词在文本中出现的频率。 So what i want to do is go through the whole BST and find the TreeNode with the max frequency(max freq). 所以我想做的是遍历整个BST并找到具有最大频率(最大频率)的TreeNode。 I tried many ways, but it doesnt seem to work. 我尝试了很多方法,但是似乎没有用。 The words are sorted on the tree alphabetically, NOT sorted by frequency. 单词在树上按字母顺序排序,而不是按频率排序。 Here is my method: 这是我的方法:

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() is a method that returns average frequency. getMeanFrequency()是一种返回平均频率的方法。 The comparison on line 3 makes sense because it is required (for my assignment) that when a word has bigger frequency than average frequency of the tree, to be inserted at the root. 第3行的比较很有意义,因为(对于我的作业)要求将单词的频率大于树的平均频率时,将其插入根。 That means that the maximum frequency I am looking for cannot be somewhere at the bottom of the tree. 这意味着我要寻找的最大频率不能在树的底部。 (Language is Java) Do you have any idea how I could make this work? (语言是Java)您是否知道如何进行这项工作?

here are some helpfull method info to better comprehend my code: class TreeNode: 这里有一些有用的方法信息,可以更好地理解我的代码:类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;
    }
}

class WordFreq: 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;
}

} }

The pseudo-code for the algorithm you want is: 所需算法的伪代码为:

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

It should not be hard to convert this pseudo-code to java. 将该伪代码转换为java并不难。

Note that this does not take advantage of the fact that a node with above average frequency is inserted at the root. 请注意,这没有利用以下事实:将高于平均频率的节点插入到根。 I do not think that it is easy to implement an algorithm that does. 我认为实现这样的算法并不容易。

If you need to do an exhaustive search of the tree (ie the highest frequency word could be anywhere) then this becomes relatively easy I believe. 如果您需要对树进行详尽的搜索(即最高频率的单词可以在任何地方),那么我相信这会变得相对容易。

However, first of all I suggest you don't set your l and r members to null in TreeNode . 但是,首先,我建议您不要在TreeNode中将lr成员设置为null。 Instead I suggest you have a private static EMPTY TreeNode which overrides appropriate methods to play the part of null - such as returing a word frequency of 0. There are lots of reasons to do it this way but rather than list them I suggest you google it! 相反,我建议您有一个私有的静态EMPTY TreeNode,它会覆盖适当的方法以发挥null的作用-例如将单词频率重新设置为0。这样做有很多原因,但是与其列出它们,我建议您用Google搜索! I'm going to assume you've done that in the code below as it makes things a lot neater. 我将假设您已经在下面的代码中完成了此操作,因为它使事情变得更加整洁。

Add a TreeNode method: 添加一个TreeNode方法:

public TreeNode maxFrequency() {
    return Arrays.asList(this, l.maxFrequenc(), r.maxFrequency()).stream()
        .max((tn1, tn2) -> tn1.wf.compareTo(tn2.wf))
        .orElse(EMPTY);
}    

Let me explain how this works in case you are not experienced with Java 8 streams. 让我解释一下,如果您不熟悉Java 8流,这将如何工作。 The Arrays.asList line creates a list of the current node and the maximum word frequency nodes from the left and right and then turns them into a stream. Arrays.asList行从左侧和右侧创建当前节点和最大字频节点的列表,然后将它们转换为流。 The max statement finds the one with the highest word frequency using a compareTo method (which you will need to add to the WordFrequency class). max语句使用compareTo方法(您需要将其添加到WordFrequency类)来找到单词频率max语句。 This returns a Optional<TreeNode> which could potentially be not present so the orElse statement returns EMPTY if there is no maximum. 这将返回一个Optional<TreeNode> ,它可能不存在,所以如果没有最大值,则orElse语句将返回EMPTY。

Finally you'll need to override this maxFrequency method in the EMPTY TreeNode to just return this to avoid infinite recursion. 最后,您需要在EMPTY TreeNode中重写此maxFrequency方法,仅返回this即可避免无限递归。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM