简体   繁体   English

将项目添加到链表的末尾

[英]Adding items to end of linked list

I'm studying for an exam, and this is a problem from an old test:我正在为考试而学习,这是旧测试中的一个问题:

We have a singly linked list with a list head with the following declaration:我们有一个带有以下声明的列表头的单向链表:

class Node {
    Object data;
    Node next;
    Node(Object d,Node n) {
        data = d;
        next = n;
    }
}

Write a method void addLast(Node header, Object x) that adds x at the end of the list.编写一个方法void addLast(Node header, Object x)在列表的末尾添加x

I know that if I actually had something like:我知道如果我真的有类似的东西:

LinkedList someList = new LinkedList();

I could just add items to the end by doing:我可以通过执行以下操作将项目添加到最后:

list.addLast(x);

But how can I do it here?但是我怎么能在这里做呢?

class Node {
    Object data;
    Node next;
    Node(Object d,Node n) {
        data = d ;
        next = n ;
       }

   public static Node addLast(Node header, Object x) {
       // save the reference to the header so we can return it.
       Node ret = header;

       // check base case, header is null.
       if (header == null) {
           return new Node(x, null);
       }

       // loop until we find the end of the list
       while ((header.next != null)) {
           header = header.next;
       }

       // set the new node to the Object x, next will be null.
       header.next = new Node(x, null);
       return ret;
   }
}

You want to navigate through the entire linked list using a loop and checking the "next" value for each node.您想使用循环浏览整个链表并检查每个节点的“下一个”值。 The last node will be the one whose next value is null.最后一个节点将是下一个值为空的节点。 Simply make this node's next value a new node which you create with the input data.只需将此节点的下一个值设为您使用输入数据创建的新节点即可。

node temp = first; // starts with the first node.

    while (temp.next != null)
    {
       temp = temp.next;
    }

temp.next = new Node(header, x);

That's the basic idea.这就是基本的想法。 This is of course, pseudo code, but it should be simple enough to implement.这当然是伪代码,但实现起来应该足够简单。

public static Node insertNodeAtTail(Node head,Object data) {
               Node node = new Node(data);
                 node.next = null;
                if (head == null){
                    return node;
                }
                else{
                    Node temp = head;
                    while(temp.next != null){
                        temp = temp.next;
                    }
                    temp.next = node; 
                    return head;
                }        
    }

If you keep track of the tail node, you don't need to loop through every element in the list.如果您跟踪尾节点,则无需遍历列表中的每个元素。

Just update the tail to point to the new node:只需更新尾部以指向新节点:

AddValueToListEnd(value) {
    var node = new Node(value);

    if(!this.head) {
        this.head = node;
        this.tail = node;
    } else {
        this.tail.next = node; //point old tail to new node
    }
        
    this.tail = node; //now set the new node as the new tail
}

In plain English:用简单的英语:

  • Create a new node with the given value使用给定值创建一个新节点
  • If the list is empty, point head and tail to the new node如果链表为空,将head和tail指向新节点
  • If the list is not empty, set the old tail.next to be the new node如果列表不为空,则将旧的 tail.next 设置为新节点
  • In either case, update the tail pointer to be the new node无论哪种情况,都将尾指针更新为新节点

Here is a partial solution to your linked list class, I have left the rest of the implementation to you, and also left the good suggestion to add a tail node as part of the linked list to you as well.这是您的链表类的部分解决方案,我将其余的实现留给了您,并且还留下了将尾节点作为链表的一部分添加给您的好建议。

The node file :节点文件:

public class Node 
{
    private Object data; 
    private Node next; 

    public Node(Object d) 
    { 
        data = d ;
        next = null;
    }

    public Object GetItem()
    {
        return data;
    }

    public Node GetNext()
    {
        return next;
    }

    public void SetNext(Node toAppend)
    {
        next = toAppend;
    }
}

And here is a Linked List file :这是一个链表文件:

public class LL
{
    private Node head;

    public LL()
    {
        head = null;
    }

    public void AddToEnd(String x)
    {
        Node current = head;

        // as you mentioned, this is the base case
        if(current == null) {
            head = new Node(x);
            head.SetNext(null);
        }

        // you should understand this part thoroughly :
        // this is the code that traverses the list.
        // the germane thing to see is that when the 
        // link to the next node is null, we are at the 
        // end of the list.
        else {
            while(current.GetNext() != null)
                current = current.GetNext();

            // add new node at the end
        Node toAppend = new Node(x);
            current.SetNext(toAppend);
        }
    }
}

The above programs might give you NullPointerException.上面的程序可能会给你 NullPointerException。 This is an easier way to add an element to the end of linkedList.这是将元素添加到链表末尾的一种更简单的方法。

public class LinkedList {
    Node head;

    public static class Node{
        int data;
        Node next;

        Node(int item){
            data = item;
            next = null;
        }
    }
    public static void main(String args[]){
        LinkedList ll = new LinkedList();
        ll.head = new Node(1);
        Node second = new Node(2);
        Node third = new Node(3);
        Node fourth = new Node(4);

        ll.head.next = second;
        second.next = third;
        third.next = fourth;
        fourth.next = null;

        ll.printList();
        System.out.println("Add element 100 to the last");
        ll.addLast(100);
        ll.printList();
    }
    public void printList(){
        Node t = head;
        while(n != null){
            System.out.println(t.data);
            t = t.next;
        }

    }

    public void addLast(int item){
        Node new_item = new Node(item);
        if(head == null){
            head = new_item;
            return;
        }
        new_item.next = null;

        Node last = head;
        Node temp = null;
        while(last != null){
            if(last != null)
                temp = last;
            last = last.next;
        }   

        temp.next = new_item;   
        return;
    }
}

The addLast() needs some optimisation as the while loop inside addLast() has O(n) complexity. addLast() 需要一些优化,因为 addLast() 中的 while 循环具有 O(n) 复杂度。 Below is my implementation of LinkedList.下面是我对 LinkedList 的实现。 Run the code with ll.addLastx(i) once and run it with ll.addLast(i) again , you can see their is a lot of difference in processing time of addLastx() with addLast().使用 ll.addLastx(i) 运行一次代码并再次使用 ll.addLast(i) 运行它,您可以看到它们在 addLastx() 和 addLast() 的处理时间上有很大的不同。

Node.java节点.java

package in.datastructure.java.LinkedList;

/**
* Created by abhishek.panda on 07/07/17.
*/
public final class Node {
    int data;
    Node next;

    Node (int data){
       this.data = data;
    }
    public String toString(){
      return this.data+"--"+ this.next;
    }
}

LinkedList.java链表

package in.datastructure.java.LinkedList;
import java.util.ArrayList;
import java.util.Date;

public class LinkedList {

    Node head;
    Node lastx;
    /**
     * @description To append node at end looping all nodes from head
     * @param data
     */
    public void addLast(int data){

        if(head == null){
            head = new Node(data);
            return;
        }
        Node last = head;
        while(last.next != null) {
            last = last.next;
        }
        last.next = new Node(data);
    }


    /**
     * @description This keep track on last node and append to it
     * @param data
     */
    public void addLastx(int data){

        if(head == null){
            head = new Node(data);
            lastx = head;
            return;
        }
        if(lastx.next == null){
            lastx.next = new Node(data);
            lastx = lastx.next;
        }

    }

    public String toString(){
        ArrayList<Integer> arrayList = new ArrayList<Integer>(10);
        Node current = head;
        while(current.next != null) {
            arrayList.add(current.data);
            current = current.next;
        }
        if(current.next == null) {
            arrayList.add(current.data);
        }
        return arrayList.toString();
    }


    public static void main(String[] args) {
        LinkedList ll = new LinkedList();
        /**
         * @description Checking the code optimization of append code
         */
        Date startTime = new Date();
        for (int i = 0 ; i < 100000 ; i++){
            ll.addLastx(i);
        }
        Date endTime = new Date();
        System.out.println("To total processing time : " + (endTime.getTime()-startTime.getTime()));
        System.out.println(ll.toString());
    }

}

循环到链表的最后一个元素,其中 next 指针指向 null 然后修改 next 指针指向一个新节点,该节点具有 data=object 和 next pointer = null

Here's a hint, you have a graph of nodes in the linked list, and you always keep a reference to head which is the first node in the linkedList.这是一个提示,您在链表中有一个节点图,并且您始终保留对 head 的引用,它是链表中的第一个节点。
next points to the next node in the linkedlist, so when next is null you are at the end of the list. next 指向链表中的下一个节点,因此当 next 为空时,您位于链表的末尾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM