【问题标题】:Reversing a singly linked list in java在java中反转单链表
【发布时间】:2015-01-05 07:07:36
【问题描述】:

我在java中从头开始制作了一个单链表。代码如下:

public class SingleLinkedList<Item>
{
private Node head;
private int size;

private class Node
{
    Item data;
    Node next;

    public Node(Item data)
    {
        this.data = data;
        this.next = null;
    }

    public Node(Item data, Node next)
    {
        this.data = data;
        this.next = next;
    }
    //Getters and setters
    public Item getData()
    {
        return data;
    }
    public void setData(Item data)
    {
        this.data = data;
    }
    public Node getNext()
    {
        return next;
    }
    public void setNext(Node next)
    {
        this.next = next;
    }

}

public SingleLinkedList()
{
    head = new Node(null);
    size = 0;
}

public void add(Item data)
{
    Node temp = new Node(data);
    Node current = head;

    while(current.getNext() != null)
    {
        current = current.getNext();
    }

    current.setNext(temp);
    size++;
}

public void add(Item data, int index)
{
    Node temp = new Node(data);
    Node current = head;

    for(int i=0; i<index && current.getNext() != null; i++)
    {
        current = current.getNext();
    }

    temp.setNext(current.getNext());
    current.setNext(temp);
    size++;
}

public Item get(int index)
{
    if(index <= 0)
    {
        return null;
    }

    Node current = head;

    for(int i=1; i<index; i++)
    {
        if(current.getNext() == null)
        {
            return null;
        }

        current = current.getNext();
    }

    return current.getData();
}

public boolean remove(int index)
{
    if(index < 1 || index > size())
    {
        return false;
    }

    Node current = head;
    for(int i=1; i<index; i++)
    {
        if(current.getNext() == null)
        {
            return false;
        }

        current = current.getNext();
    }

    current.setNext(current.getNext().getNext());
    size--;
    return true;
}

public String toString()
{
    Node current = head.getNext();
    String output = "";
    while(current != null)
    {
        output+=current.getData().toString()+"  ";
        current = current.getNext();
    }

    return output;
}

public int size()
{
    return size;
}

public void reverse()
{
    Node current = head;
    Node prevNode = null;
    Node nextNode;

    while(current!=null)
    {
        nextNode = current.getNext();
        current.setNext(prevNode);
        prevNode = current;
        current = nextNode;
        System.out.println(prevNode.getData());
    }

    head = prevNode;

}

}

如你所见,我只在类中添加了 reverse 函数。

但是当我尝试实际使用该类时,它在我尝试反转它后给出了 NullPointerException。

为了检查功能,我使用了另一个名为 TEST 的类。代码如下:

public class TEST
{

    public static void main(String[] args)
    {
        SingleLinkedList<Integer> list = new SingleLinkedList<Integer>();

        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);

        System.out.println(list.toString());

        list.reverse();
        System.out.println(list.toString());

    }
}

输出如下:

1  2  3  4  5  
null
1
2
3
4
5
Exception in thread "main" java.lang.NullPointerException
    at SingleLinkedList.toString(SingleLinkedList.java:129)
    at TEST.main(TEST.java:20)

我试图打印 prevNode 的值来检查它是否没有取值......但确实如此。 怎么办?

【问题讨论】:

  • 对于这样的问题,最好的方法是拿纸和铅笔,画一个例子,看看指针是如何随着你在程序中的动作而变化的。
  • 我都试过了。找不到任何东西。也许它就是我这样做的方式,但我仍然被卡住了。你能帮帮我吗?

标签: java linked-list singly-linked-list


【解决方案1】:

实际上,您的反向方法看起来不错。

问题在于您的 toString() 方法。
创建新列表时,会创建一个数据为空的初始元素。
您的 toString 方法会跳过第一个元素,因此只要您不反转列表,它就可以正常工作。
但是,当您反转列表时,该空元素将成为最后一个元素,并且当您在 current.getData() 为空时为最后一个元素调用 output+=current.getData().toString()+" "; 时,您会得到 NullPointerException

你有几个选择:

  1. 您的 reverse 方法可以首先保留初始 null 元素(即反转列表的其余部分,但保持头部相同)。这样 toString 可以保持不变。
  2. 消除初始空元素。这样您的 toString 方法就不必跳过任何内容。

先保留空元素:

public void reverse()
{
    Node current = head.getNext();
    Node prevNode = null;
    Node nextNode;

    while(current!=null)
    {
        nextNode = current.getNext();
        current.setNext(prevNode);
        prevNode = current;
        current = nextNode;
        System.out.println(prevNode.getData());
    }

    head.setNext(prevNode);

}

【讨论】:

  • @abhyuditjain 添加一些建议
  • 请不要介意我知识贫乏。我是新的。只是学习。我不完全明白你想说什么。但我尝试实施更改,现在有 2 个问题:(1)反转后不显示最后一个节点,(2)如果我实施更改,反转后 toString() 正在工作。
  • @abhyuditjain 添加了建议的修复以反转。虽然没有测试它。替代修复需要更改更多方法,因此如果您选择尝试,我将其留给您。
  • @abhyuditjain 你试过我刚刚发布的代码了吗?你不必改变 toString
【解决方案2】:

问题出在 SingleLinkedList.java toString() 方法中

在下面尝试它工作正常

    public String toString() {
        Node current = head;
        String output = "";
        while (current != null) {
//            output += current.getData().toString() + "  ";
            output += String.valueOf(current.getData()) + "  ";
            current = current.getNext();
        }

        return output;
    }

【讨论】:

  • Eran 在不更改 toString() 方法的情况下解决了我的问题。无论如何,谢谢。
【解决方案3】:
 while(current!=null)

这是你的问题。当你点击最后一个节点时,你得到的“下一个”节点实际上是空的。

试试改成

while(current!=null&&current.getNext()!=null)

编辑:实际上不确定该解决方案是否有效。尝试在循环末尾添加一个条件:

if(current.getNext()==null)
    break;

编辑(再次:/):

好吧,抱歉,我没有想清楚。

将最后的 if 语句更改为:

if(current.getNext()==null){
    current.setNext(prevNode);
    break;
}

实际的空指针在 toString 中。这是你要做的:

将while条件改为

while(current != null&&current.getData()!=null)

因为否则如果 current 指向 null 那么你会得到一个异常。

太累了。

【讨论】:

  • 我试过了,但现在最后一个节点根本不显示。
  • 第一个没有做任何不同的事情。第二个也给出了 nullpointerexception
  • 好的,我现在要实际测试一下
  • 不工作:(同样的错误。我现在受够了这个:x
  • 感谢您的努力,但无论如何都不会显示最后一个节点。无论我尝试什么,toString() 方法都可以在反转之前或之后工作。
猜你喜欢
  • 2018-10-16
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
  • 2012-01-30
  • 2016-03-19
  • 2016-09-29
相关资源
最近更新 更多