java中的链接列表

时间:2013-07-15 20:31:24

标签: java list

我必须为链表类编写一个非常简单的方法,但我遇到了一些问题。这个名为squish()的方法采用此列表,并且在两个或更多连续项目的位置 相等(使用equals()进行比较),它会删除重复的节点,以便只保留一个连续的副本。因此,在完成程序后,此列表中没有两个连续项目相同。

执行squish()后,列表可能会比squish()开始时短。没有额外的项目可以弥补被删除的内容。

例如,如果输入列表为[ 0 0 0 0 1 1 0 0 0 3 3 3 1 1 0 ],则输出列表为[ 0 1 0 3 1 0 ]

这是我的方法:

public void squish() {
 SListNode current = head;
 boolean end =false;

  while(end == false )
    {


      if(!current.item.equals(current.next.item))
          current=current.next;
      else
      {
          while(current.item.equals(current.next.item) && current.next !=null)
              current.next=current.next.next;
          current=current.next;

      }
    if (current==null)
        end=true;
    }


      }

这是执行代码的一个小主要部分。

public class main {
public static void main(String args[])
{



    int[] test6 = {6, 6, 6, 6, 6, 3, 6, 3, 6, 3, 3, 3, 3, 3, 3};
    SList list6 = new SList();
    for (int i = 0; i < test6.length; i++) {
      list6.insertEnd(new Integer(test6[i]));
    }
    System.out.println("squishing " + list6.toString() + ":");
    list6.squish();
    String result = list6.toString();
    System.out.println(result);


    int[] test5 = {3, 7, 7, 7, 4, 5, 5, 2, 0, 8, 8, 8, 8, 5};
    SList list5 = new SList();
    for (int i = 0; i < test5.length; i++) {
      list5.insertEnd(new Integer(test5[i]));
    }

    System.out.println("squishing " + list5.toString() + ":");
    list5.squish();
    result = list5.toString();
    System.out.println(result);

}

}

调试代码我可以看到该方法工作正常..只在列表的末尾,他转发了一个空异常指针。你能帮助我吗?感谢

3 个答案:

答案 0 :(得分:4)

我会这样做:

public void squish() {
    SListNode current = head; //1

    if(current = null) return;  //1a

    while(current.next != null) { //2
       if(current.item.equals(currennt.next.item))
          current.next = current.next.next;  //3
       else 
          current = current.next;  //4
    }
}

这是教授为递归分配的东西,虽然大多数专业人员不使用递归,但我已经设置了这种方法。

第1行是init,您将遍历列表的指针指向链接列表的开头。

第1a行如果列表中没有元素,那么我们返回。

第2行是基本情况。如果我们在列表中只有一个元素,那么无所事事。

第3行是归纳,如果我们指向一个节点,我们检查隔壁的节点。如果它们具有相等的值,那么我们可以删除隔壁的节点。

第4行是第3行的else,我们查看了隔壁的节点,发现它不相等。因此,我们遍历清单。

手动遍历问题中提供的测试数据可能是一项有用的练习,然后在我的示例中添加一些System.out.println以查看您是否正确。我今天必须用一些棘手的代码来解决发生了什么。

答案 1 :(得分:4)

问题出在这一行:

while(current.item.equals(current.next.item) && current.next !=null)

这里,条件的第一部分访问current.next.item,即使current.next为空,因为条件的第二部分(current.next !=null)在后检查 em>第一个(仅当第一个评估为true时,见下文)。要修复它,只需反转条件:

while(current.next !=null && current.item.equals(current.next.item))

这样,表达式current.item.equals(current.next.item)只会在current.next !=null为真(short-circuit evaluation)时执行,即在安全的情况下执行。

另外,我认为你可以放弃第一个if声明。看看@ Pete关于如何简化方法的答案。

答案 2 :(得分:2)

当在最后一次迭代中执行第if(!current.item.equals(current.next.item))行时,current.next指向null,因为current是列表中的最后一项,实际上没有下一个项目

修改

现在,在您的评论中,我看到您获得了行中的NullPointerException

while(current.item.equals(current.next.item) && current.next !=null)

好吧,你应该只是将这两个条件相互替换:首先验证current.next不是null,然后才等同于currentnext

while(current.next !=null && current.item.equals(current.next.item))

顺便说一句,当你的列表只有一个元素时,你仍然会在行if(!current.item.equals(current.next.item))中得到NPE。例如,要修复此问题,只需检查是否head.next == null。如果是这样,请不要首先启动while循环。