简体   繁体   中英

node delete: terminator node in a singly linked list?

I have an implementation of deleting the current node. The condition is that: we only know the current node.

The way of doing this is that:

  • copy the data of next node into the current one
  • then delete the next node

as the following implementation:

public class ListNode<T> {

  private ListNode<T> next = null;
  private T data;

  public ListNode(T data) {
    this.data = data;
  }

  /*
   * Add a new node after the current node
   * Time Complexity: O(1)
   */
  public void add(T data) {
    ListNode<T> newNode = new ListNode<T>(data);
    newNode.setNext(this.getNext());
    this.setNext(newNode);
  }

  /*
   * Delete the current node
   * Time Complexity: O(1)
   */
  public T delete() {
    ListNode<T> nextNode = next;
    if (nextNode == null) { /* The current node is the last node. */
      return null;
    }

    T nextData = nextNode.getData();
    this.setData(nextData);
    this.setNext(nextNode.getNext());
    return nextData;
  }

  /* getters and setters */

}

However, there is an exception: this will not work if the current node is the last node on the list.

I can think of a way of solving this problem:

  • have a special node as TerminatorNode , which is always at the end of a linked list.

I would like to know: How to implement it? Or, what kind of class this kind of node should be?

EDIT 1: Just to be clear, my question is: how I can I always delete the current node, even if it is the last node on the linked list? I would like to have a TerminalNode , which is always at the end of the linked list, which only just represents the linked list end. (It is something like \\0 at the end of a string.) Then other normal node can be always deleted using the same method with time O(1).

EDIT 2: This is some statement on Cracking the Coding Interview:

You could, for example, consider marking the node as dummy.

What does that mean?

在此处输入图片说明 在此处输入图片说明

For simplicity, let's represent the terminal node like a LinkedNode with data and next as null . Let's also assume that a terminal node is the only valid way to end a list.

private boolean isTerminalNode() {
    return this.getData() == null && this.getNext() == null;
}

If the end of the list is always a terminal node, any node can be deleted except the terminal.

/*
 * Delete the current node Time Complexity: O(1)
 */
public T delete() {
    if (this.isTerminalNode()) {
        // Cannot delete the terminal node.
        // Either throw an IllegalArgumentException or return silently
        return null;
    }

    ListNode<T> nextNode = this.getNext();
    this.setData(nextNode.getData());
    this.setNext(nextNode.getNext());
    return this.getData();
}

However, now we might encounter a similar problem when adding after a node.

/*
 * Add a new node after the current node Time Complexity: O(1)
 */
public void add(T data) {
    if (this.isTerminalNode()) {
        // Cannot add a node after the terminal node.
        // Either throw an IllegalArgumentException, return silently, or add
        // the data at the current position and create a new terminal node.
        throw new IllegalArgumentException("Cannot add a node after the terminal node");
    }

    ListNode<T> newNode = new ListNode<T>(data);
    newNode.setNext(this.getNext());
    this.setNext(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