【问题标题】:Manual Linked List - Insert before method手动链表 - 在方法之前插入
【发布时间】:2011-07-26 00:40:01
【问题描述】:

这是我们在课堂上做的练习的一部分,我只是想不通......

需要的方法是insertBefore(object data)方法,当用户选择这个方法时,它会提示它在参考数据之前输入要插入的数据(用户输入)

它应该如何运行的示例:

// assuming linked list has data 1,2,3 inserted already

Choose Method:
1)Insert Before

choice: 1 // input by user


====Insert Before====
Enter Reference data: 2 // input by user
Enter Data to be inserted: 5 // input by user

supposed output: 1,5,2,3

这是我的练习代码:(这是在一个名为 LinkList 的类中,带有变量

protected int end;
protected Node start;

还有一个叫做 Node 的内部类)

private class Node
{
    public char data;
    public Node next;
    public Node(char data)
    {
        this.data = data;
    }
}


public void insertBef(char ref,char data)
{
    Node temp = new Node(data);
    Node current = start;

    if(end!=0)
    {
        for(int i = 1; i<end; i++)
        {
            if(current == start)
            {
                Node newNode = start;
                newNode.data = current.data;
                newNode.next = temp;
                current = current.next;
            }
            else if(current.data == ref)
            {
                Node newNode = current;
                newNode.data = current.data;
                newNode.next = temp;
                current = current.next;
            }
        }
        end++;

    }
    else
    {
        temp.next = start;
        start = temp;
    }
    end++;
}

但是当我运行我的代码时,它会输出3,5,而不是1,5,2,3!我看不出我哪里出错了……

谁能告诉我错误在哪里,并解释我如何解决它?

我知道要能够在参考值之前插入,您应该:

  • 为新数据创建一个新节点
  • 为参考值和链接做一个临时节点
  • 让参考值之前的数据链接指向新节点,让新节点的链接指向临时节点

我似乎无法弄清楚如何在 Java 代码中实现它...

【问题讨论】:

  • end 是否表示列表中的节点数?我注意到 end 不是 0 时会增加两次
  • 请发SSCCE

标签: java linked-list


【解决方案1】:

在编程时,如果它看起来很难,那么你可能会走错路......

只需一行代码即可完成任务!

list.add(list.indexOf(reference), data);

这是包装为insertBefore 方法的这一行:

public static void insertBefore(List<Integer> list, int reference, int data) {
    list.add(list.indexOf(reference), data);
}

这是使用您的示例进行的测试:

public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>(Arrays.asList(1, 2, 3));
    insertBefore(list, 2, 5);
    System.out.println(list);
}

输出:

[1, 5, 2, 3]

注意:如果找不到引用元素,此代码将引发异常。
我会留给你来堵住那个洞。

【讨论】:

  • 我认为 OP 需要实现一个不使用列表的列表。
【解决方案2】:

第一件事:for 循环对于链表来说通常是个坏主意。 while 循环要好得多;你可以做类似while(next != null)的事情。

查看您的代码,您似乎遇到了一些问题。

您的 for 循环过于复杂,似乎没有多大意义。你的循环应该是这样的:

  1. 获取头节点
  2. 开始循环遍历列表,检查下一个节点的值
  3. 一旦您发现下一个节点的值就是您要查找的值,就创建一个新节点。
  4. 通过将新节点的 Next 值设置为等于当前节点的 Next 值来插入新节点,然后将当前节点的下一个值设置为新节点。
  5. 从函数返回。

您的中间要点实际上是不必要的,我不知道您使用 end 做什么。无论如何,您似乎已经掌握了基本原理,所以我不会觉得我通过发布代码来破坏您。

现在,我不确定您的 start 是什么。它是否保存一个值,或者它是一个专用的头节点?我会投票给专用的头节点,我通常发现它更容易使用,因为您不需要为数字应该在头之前的特殊情况添加代码。所以你的起始节点应该是“空的”;它持有的值被忽略,它唯一的用途是保留指向列表中第一个合法节点的指针。如果这样做,insertBef 方法将变得非常简单。注意:要遵循未经测试的代码。

public void insertBef(char ref, char data)
{
    Node current = start;

    while( current.next != null )
    {
        if( current.next.value == ref )
        {
            Node n = new Node(data);
            n.next = current.next;
            current.next = n;
            return;
        }

        current = current.next;
    }
}

请不要只是复制代码。如果您有任何问题,请发布它们,我会尽力回答。

【讨论】:

  • 我很抱歉回复得太晚了......嗯,我似乎明白了你的意思,并且更好地理解了链接列表......谢谢。有时我真的倾向于忽略一些事情......仍然......再次感谢你! :)
  • @Mannimarco,你为什么说“for 循环对于链表来说通常是个坏主意”?您的while 可以写成for,如下所示:for (Node current = start; current.next != null; current = current.next) {...}。我试图理解为什么重写的表格是一个“坏主意”。
  • 如果 ref 输入值是第一个节点,这将不起作用,因为您正在检查从第二个节点开始的值。我知道 insertFirst() 会处理这个问题,但是这个方法也应该允许在第一个值之前插入。
猜你喜欢
  • 1970-01-01
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 2011-12-23
  • 1970-01-01
  • 2020-05-20
相关资源
最近更新 更多