9

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.

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?

5
  • 1
    Why do you need to pass in Node header to append something to the end of the list? Commented Mar 8, 2011 at 18:11
  • write your own implementation for addLast(Node header, Object x) that adds x at the end of the list google for adding element at end of singly linkedlist in java Commented Mar 8, 2011 at 18:12
  • 1
    @therin - probably ask his professor that. Commented Mar 8, 2011 at 18:16
  • @therin, this is the exact question, idk. Commented Mar 8, 2011 at 18:16
  • Try just adding the method to the Node class as a static method, and looping to the end of the Node header, then adding a new node to the end of that list. Commented Mar 8, 2011 at 18:22

9 Answers 9

17
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;
   }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Yes, there is always a way to loop recursively. Use header == null as the base case (where you will stop) and call addLast with header.next.
So i would make the if statemtn just return; And the the last header.next be header.next=addLast(header,null)?
Sort of, you need to pass in x through the recursive loop: addLast(header, x) and then if header == null, create the new node, add X to it, and return the new node. If not in the base case, you should return the result of addLast
Your code runs in O(n) time, but this operation should be O(1). If you keep track of the tail node, you don't need to loop through every element in the list. All you do is update the tail to point to the new node.
@TomDane The problem statement indicates that we must take as input the head node while appending to the end of the list.
8

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.

1 Comment

The most important part is the base case, where first is null. Should be handled appropriately (i.e. don't throw a NullPointerException)
4
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;
                }        
    }

Comments

4

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) { //if the list is empty, set head and tail to this first node
        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
  • If the list is not empty, set the old tail.next to be the new node
  • In either case, update the tail pointer to be the new node

4 Comments

Thumbs up for O(1)
Useful when you need add multiple elements to the end, don't need to scroll entire list every time.
@tomdane this.tail = node; does not ovewrite this.tail.next ?
@arjayads nope it doesn't overwrite. Think of tail as not a node itself, but just a pointer to any node. First we use the tail pointer to set the .next property of a node. Then we point the tail to a different node. But the previous node remains unchanged.
1

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);
        }
    }
}

Comments

0

loop to the last element of the linked list which have next pointer to null then modify the next pointer to point to a new node which has the data=object and next pointer = null

Comments

0

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.
next points to the next node in the linkedlist, so when next is null you are at the end of the list.

Comments

0

The addLast() needs some optimisation as the while loop inside addLast() has O(n) complexity. Below is my implementation of 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().

Node.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());
    }

}

Comments

0

The above programs might give you 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;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.