如何在 Java 中返回 BinaryTree 中最频繁的元素

问题描述

我想返回 BinaryTree 中最频繁的值的数量我有 BinaryClass,其中包含许多方法,如 add、contain、isEmpty、counter、iterator 等。我尝试实现此方法 public int getMaxFrequency(),但在标记行出现 StackOverFlowException 问题。

当我运行我的代码时,我得到StackOverFlow Exception,任何人都可以帮助我,

我是 BinaryTree 的新手。

请帮帮我。

enter code here
public class TreeSetCounter<T extends Comparable<T>> implements    Iterable<T>{
public Node<T> root; 
int size;
int count=0;

public TreeSetCounter() {
    root = null;
    size = 0;
   }
 public int counter(T t) {
 return counterRecursive(root,t);
  }

   public int counterRecursive(Node<T> root,T t) {
   int count = 0;
   if(root == null) {
        return 0;
          }
    if(root.value.equals(t)) {
      count++; 
      }
   count = count + counterRecursive(root.left,t)+           counterRecursive(root.right,t);
   return count; }


 public int getMaxFrequency(){
 
  return inorder(root);           
  }

  public int inorder( Node<T> prev) {
 
    int count = 1,max = 0;
    if (root == null) {
        return 0;}
    List<T> list = new ArrayList<>();
    inorder(root.left);   // I get the Exception att this row code.
    while (prev != null) {
    if (root.value == prev.value)
            count++;
        else
            count = 1;
    }
    
    if (count > max) {
        max = count;
        list.clear();
        list.add(root.value);
    } else if (count == max) {
        list.add(root.value);
    }
    prev = root;
    inorder(root.right);
    return max;
}

enter code here
Node.java
public class Node <T>{
T value;
int counter;
Node<T> left;
Node<T> right;

Node(T value,int count) {
    this.value = value;
    right = null;
    left = null;
    this.counter= count;
    }

enter code here
public static void main(String[] args) {
    TreeSetCounter <String> tsc= new TreeSetCounter<String>();
    tsc.add("java");
    tsc.add("java");
    tsc.add("not");
    tsc.add("cool");
    tsc.add("java");
    tsc.add("is");
    tsc.add("java");
    tsc.add("good");
    System.out.println(tsc.getMaxFrequency());}

解决方法

为您的计数器函数尝试这样的操作:

public int counter (T t) {
  if (root == null) return 0;
  
  int count = 0;
  if (root.value.equals(t))
    count++;
  
  count += counterRecursive(root.left,t);
  count += counterRecursive(root.right,t);

  return count;
}

public int counterRecursive (Node<T> root,T t) {
   if (root == null) return 0;
   
   if (root.value.equals(t))
    return 1 + counterRecursive(root.left,t) + counterRecursive(root.right,t);
   else
    return counterRecursive(root.left,t);
}

counter 函数看起来像是要使用的主要方法,而 counterRecursive 是您的辅助函数。更复杂的递归解决方案通常具有这种设计模式。

从斐波那契数列考虑:

public static int fibonacci (int n) {
  return (n <= 1) ? n : fibonacci(n - 1) + fibonacci(n - 2);
}

这应该可以帮助您调试 inOrdergetMaxFrequency。我会在 counter 中使用 getMaxFrequency,而我会浏览其余部分。一般来说,使用 HashMapHashTable 更适合跟踪计数。

尝试这样的事情:

public int getMaxFrequency () {
    if (root == null) return 0;
        
    HashMap<T,Integer> counts = new HashMap<T,Integer>();
        
    int count = counter(root.value);
    counts.put(root.value,count);

    // traverse the tree and grab counts
    int left = getMaxFrequencyHelper(root.left,counts,count);
    int right = getMaxFrequencyHelper(root.right,count);

    return left > right ? left : right;
}

private int getMaxFrequencyHelper (Node<T> node,HashMap<T,Integer> counts,max) {
    if (node == null) return max;

    if (!counts.containsKey(node.value))
        counts.put(node.value,counter(node.value));

    int _max = counts.get(node.value) > max ? counts.get(node.value) : max;

    int left = getMaxFrequencyHelper(node.left,_max);
    int right = getMaxFrequencyHelper(node.right,_max);

    return left > right ? left : right;
}

此技术称为 memoization,其中先前的计数为 cached 中的 HashMap