简体   繁体   中英

Java Linked List - add method

Data structures class, implementing a singly linked-list with head, tail and current nodes. Having trouble with a method, could use a nudge in the right direction.

From the assignment, write the method:

add( item ) : adds the item (String) after the current node in the list and sets the current pointer to refer to the new node.

My attempt:

public void add(String item)
{
    if(curr != null)
    {
        Node newNode = new Node(item, curr.next);
        curr.next = newNode;
        curr = newNode;
    }
    else
    {
        head = tail = new Node(item, null);
        curr = head;
    }
}

My add method only seems to work when I'm adding items to the middle of the list, not on either end. If I use it to add a few items and then print the list, only the first one I added will be on the list, while my prepend and append methods have tested just fine.

Is there any glaring issue with my code? I feel like I'm missing something obvious.

All:

public class LinkedList {
    Node head = null; /* Head of the list */
    Node tail = null; /* Tail of the list */
    Node curr = null; /* Current node in the list */

    public void prepend(String item) {
        if (head == null) {
            head = tail = new Node(item, null);
            curr = head;
        } else {
            head = new Node(item, head);
            curr = head;
        }
    }

    public void append(String item) {
        if (head == null) {
            head = tail = new Node(item, null);
            curr = tail;
        } else {
            tail.next = new Node(item, null);
            tail = tail.next;
            curr = tail;
        }
    }

    public void add(String item) {
        if (curr != null) {
            Node newNode = new Node(item, curr.next);
            curr.next = newNode;
            curr = newNode;
        } else {
            head = tail = new Node(item, null);
            curr = head;
        }
    }

    public void delete() {
        if (curr.next == null) {
            Node temp = head;
            while (temp.next != curr) {
                System.out.println(temp.item);
                temp = temp.next;
            }
            temp.next = null;
            curr = head;
        }
    }

    public void find(String item) {
        Node temp = new Node(curr.item, curr.next);
        if (item.equals(temp.item))
            curr = temp;
        else {
            temp = temp.next;
            while (temp.next != null && temp != curr) {
                if (item.equals(temp.item))
                    curr = temp;
            }
        }
    }

    public String get() {
        if (curr != null)
            return curr.item;
        else
            return "";
    }

    public boolean next() {
        if (curr != tail) {
            curr = curr.next;
            return true;
        } else
            return false;
    }

    public void start() {
        curr = head;
    }

    public void end() {
        curr = tail;
    }

    public boolean empty() {
        if (head == null)
            return true;
        else
            return false;
    }
}

Node class:

class Node {
    Node next;
    String item;

    Node(String item, Node next) {
        this.next = next;
        this.item = item;
    }
}

There is indeed a problem in add : it doesn't update tail when nodes already exist. Consider this sequence of actions:

LinkedList list = new LinkedList(); 
list.add("one");
list.add("two");
list.append("three");

If you were to then print it using this:

public void print() {
    Node curr = this.head;
    while(curr != null) {
        System.out.println(curr.item);
        curr = curr.next;
    }
}

Like this:

list.print();

You'd get the following output:

one
three

This happens because tail -- which append relies on -- continues to point to the first Node after the second add operation is performed.

I don't see any problems here, so I would guess the issue is elsewhere.

Okay, the only issue I see there is in delete:

public void delete()
{
    Node temp = head;

    while(temp != null && temp.next != curr) {
         System.out.println(temp.item);
         temp=temp.next;

    }

    if (temp != null && temp.next != null) {
        temp.next = temp.next.next;
    }
    curr = head;

}

I think I have found your problem. If you use append() you add it directly after the tail. But when you have added previous nodes after the tail you don't set your tail to the new node. This means that once you call append() twice you loose all the nodes that you have added after the first append().

Brief example:

public static void main(String[] args) {
    LinkedList list = new LinkedList();
    list.add("First add");
    list.append("First Append");
    list.add("Second add");
    list.prepend("First prepend");
    list.add("Third add");
    list.prepend("Second prepend");
    list.add("fourth add");
    list.append("Second Append");
    list.add("Fifth add");
    list.add("Sixth add");

    list.start();
    do {
        System.out.println(list.get().toString());

    } while (list.next());
}

Output:

Second prepend
fourth add
First prepend
Third add
First add
First Append
Second Append

Conclusion: "Second Add" is lost, as well as "Fifth add" and "Sixth add" because your next() method stops as soon as it reaches the tail. You need to always update the tail if you add a new node in the end.

Hope this helps. Cheers, Chnoch

I think the problem is

if (curr != null) {
    Node newNode = new Node(item, curr.next); //<-- here (curr.next)

//and

Node(String item, Node next) {
    this.next = next; //<-- here

Try ( Edited ):

Node newNode = new Node(item, curr); // pass curr to the constructor of Node
curr = newNode;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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