Listnode实现count occurrences方法的问题(递归)

Listnode problem implementing the count occurrences method (recursive)

大家好,我正在尝试实现 ListNode,但我对这两种方法都有问题

我知道它可以用迭代方法实现,但我想使用递归,所以请告诉我我做错了什么:

public class ListNode2<E> {

    public E data;

    public ListNode2<E> next;

    public ListNode2(){
        this.data=null;
        this.next=null;
    }
    public ListNode2(E data, ListNode2<E> n) {
        this.data = data;
        next= n;
    }

    public ListNode2(E data) {
        this.data = data;
        next=null;
    }

    public E getData() {
        return this.data;
    }

    public ListNode2<E> getNext() {
        return this.next;
    }

    public ListNode2<E> addFirst(E data) {
        return new ListNode2<>(data, this);
    }
    public boolean contains(E data){

        if ( data ==null && this.getData()==null )
            return true;

        if (data!=null && (data.equals(this.getData())))
            return true;

        if (this.next==null)//remove the next and we have nullpointer exception but right results :( 
            return false;

        return this.getNext().contains(data);
    }    

    public int countIf(E data) {
        //i was missing the getNext() but now i get for the first element zero
        if(this.getNext()==null)
            return 0;

        if (data ==null && this.getData() == null )
            return 1+ getNext().countIf(data);

        if ( data!= null && (data.equals(this.getData())) )
            return 1 + getNext().countIf(data);



        return getNext().countIf(data);
    }

    public int size() {
        if (getNext() == null) {
            return 1;
        } else {
            return 1 + getNext().size();
        }
    }

    @Override
    public String toString() {
        return data + " ";
    }

    public static void main(String[] args) {

        ListNode2<Integer> list = null; // Leere Liste.
        list = new ListNode2<Integer>(1); // ergibt 1.
        list = list.addFirst(2);
        list = list.addFirst(3);
        list = list.addFirst(4);
        int size = list.size();

        System.out.println(size);

        System.out.println("countif 1 "+ list.countIf(1));//this gives 0 why??
        System.out.println("countif 2 "+ list.countIf(2));
        System.out.println("countif 3 "+ list.countIf(3));
        System.out.println("countif 5 "+ list.countIf(5));
        System.out.println("countif null "+ list.countIf(null));
        System.out.println("countif 7 "+ list.countIf(7));
    }
}

我在 countIf 方法中做错了什么?我好像想不通?

编辑: 按照用户的建议更正了 contains 方法: Ole V.V. 。 但在 countIF() 上应用相同的提示:它看起来像这样

    public int countIf(E data) {

    if (data!= null && (data.equals(this.getData())) )
        return 1 + getNext().countIf(data);//this line is the 74

    if ( data ==null && this.getData() == null )
        return 1+ getNext().countIf(data);

    if(this.getNext()==null)
        return 0;


    return getNext().countIf(data);   //this line is the 83 
}

输出:

    Exception in thread "main" java.lang.NullPointerException
    at de.hsmannheim.inf.pr2.ads.ListNode2.countIf(ListNode2.java:74)
    at de.hsmannheim.inf.pr2.ads.ListNode2.countIf(ListNode2.java:83)
    at de.hsmannheim.inf.pr2.ads.ListNode2.countIf(ListNode2.java:83)
    at de.hsmannheim.inf.pr2.ads.ListNode2.countIf(ListNode2.java:83)
    at de.hsmannheim.inf.pr2.ads.ListNode2.main(ListNode2.java:126)
/home/pi/.cache/netbeans/11.0/executor-snippets/run.xml:111: The following error occurred while executing this line:
/home/pi/.cache/netbeans/11.0/executor-snippets/run.xml:68: Java returned: 1
BUILD FAILED (total time: 0 seconds)

这是关于您执行检查的顺序。

    public boolean contains(E data){

        if (this.next==null)//remove the next and we have nullpointer exception but right results :( add the 
            return false;

        if ( data ==null && this.getData()==null )
            return true;

        if (data!=null && (data.equals(this.getData())))
            return true;

        return this.getNext().contains(data);
    }    

现在如果要查找的数据元素在最后一个节点中,会发生什么情况?首先检查 next 是否为 null。这是。所以你returnfalse。您永远不会发现数据就在同一个节点中。

相反,您需要将 null 检查放在对内容的两次检查之后(当然,仍然在包含递归调用的 return 语句之前)。

编辑: countIf() 的情况类似但更复杂。同样,您首先需要测试数据是否是要搜索的数据,如果是,则对其进行“计数”,获得 0 或 1。然后测试 nextgetNext() 是否为 null。如果是,return 获得的计数。最后还需要将之前得到的计数加到递归调用的结果中。

顺便说一句,代码不错。

您的 countIf 函数没有考虑第一个元素的值。 您可以通过以下方式更正:

public int countIf(E data)
{
  boolean isDataEq = Objects.equals(data, this.data);

  if(getNext() == null)
  {
    return isDataEq ? 1 : 0;
  }

  int nextCount = getNext().countIf(data);
  return isDataEq ? 1 + nextCount : nextCount;
}

您可以通过以下方式简化 contains 函数:

public boolean contains(E data)
{
  if (Objects.equals(data, this.data)) return true;
  if (next==null) return false;
  return next.contains(data);
}