Home > Software design >  How do I add elements (integers or string) in the middle of my doubly-linked list? -Java
How do I add elements (integers or string) in the middle of my doubly-linked list? -Java

Time:10-19

  1. This code allows me to create a linked list and I want to be able to add elements between two nodes.
  2. I'm having trouble understanding how to set it up so I can insert a number between 40 and 30.

public class DoublyLinkedList<E> {

    private static class Node<E> {
        //Node Fields
        private E element;
        private Node<E> prev;
        private Node<E> next;

        // Node Constructor
        public Node(E e, Node<E> p, Node<E> n) {
            this.element = e;
            this.prev = p;
            this.next = n;
        }

        // Node Methods
        public E getElement() {
            return element;
        }

        public Node<E> getPrev() {
            return this.prev;
        }

        public Node<E> getNext() {
            return this.next;
        }

        public void setPrev(Node<E> p) {
            this.prev = p;
        }

        public void setNext(Node<E> n) {
            this.next = n;
        }

    }

    // DLinkedList Fields
    private Node<E> header;
    private Node<E> trailer;
    int size;

    // DLinkedList Constructor
    public DoublyLinkedList() {
        this.header = new Node<>(null, null, null);
        this.trailer = new Node<>(null, this.header, null);
        this.header.setNext(this.trailer);
    }

    // DLinkedList Methods
    public int size() {
        return this.size;
    }

    public E first() {
        if (isEmpty()) {
            return null;
        }
        return this.header.next.getElement();
    }

    public E last() {
        if (isEmpty()) {
            return null;
        }
        return this.trailer.prev.getElement();
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void addFirst(E e) {
        addBetween(e, this.header, this.header.getNext());
    }

    public void addLast(E e) {
        addBetween(e, this.trailer.getPrev(), this.trailer);
    }

    public void addBetween(E e, Node<E> predecessor, Node<E> successor) {
        Node<E> newest = new Node<>(e, predecessor, successor);
        predecessor.setNext(newest);
        successor.setPrev(newest);
        this.size  ;
    }

    public E removeFirst() {
        if (this.isEmpty()) {
            return null;
        }
        return this.remove(header.getNext());
    }

    public E removeLast() {
        if (this.isEmpty()) {
            return null;
        }
        return this.remove(trailer.getPrev());
    }

    public E remove(Node<E> e) {
        e.next.setPrev(e.prev);
        e.prev.setNext(e.next);
        this.size--;
        return e.getElement();
    }

    public String toString() {
        StringBuilder sb = new StringBuilder("(");
        Node<E> walk = this.header.next;
        while (walk != this.trailer) {
            sb.append(walk.element);
            if (walk.next != this.trailer)
                sb.append("--> ");
            walk = walk.next;
        }
        sb.append(")");
        return sb.toString();
    }
    // Node myList = new Node<E>(null, trailer, header);
    // myList.e.addFirst

    // Node myList2 = new Node<E>(null, 1, null);
}


class Main {
    public static void main(String[] args) {
        // create a DoublyLinkedList object
        DoublyLinkedList Node = new DoublyLinkedList();
        // Add nodes to the list
        Node.addFirst(10);
        Node.addFirst(20);
        Node.addFirst(30);
        Node.addFirst(40);
        Node.addFirst(50);
        Node.removeFirst();
        Node.removeLast();
        //Node.addBetween(Node, null, null);

        // print the nodes of DoublyLinkedList
        System.out.println(Node);
    }
}

CodePudding user response:

Start by changing addBetween to return the node.

    public Node<E> addBetween(E e, Node<E> predecessor, Node<E> successor) {
        Node<E> newest = new Node<>(e, predecessor, successor);
        predecessor.setNext(newest);
        successor.setPrev(newest);
        this.size  ;
        return newest;
    }

Change addFirst and addLast to return that node. I'll only show addFirst:

    public Node<E> addFirst(E e) {
        return addBetween(e, this.header, this.header.getNext());
    }

Save the nodes for 30 and 40:

Node<Integer> node30 = Node.addFirst(30);
Node<Integer> node40 = Node.addFirst(40);

Then you can use addBetween:

Node.addBetween(newNumber, node30, node40);

CodePudding user response:

  • You need not expose the class Node and indeed you made it private. But then you cannot navigate by Node, just by E. So remove(Node) is not possible as public method.
  • Node's methods could be private too.
  • Node need not be parametrized by <E>. That can even give serious programming problems, as there then are two Es. Remove it.
  • addBetween is nicely symmetric, but successor is redundant. I would remove it as parameter and make it a local variable.
  • Rename the local variable Node to list.

So:

private E removeNode(Node node) {
    node.next.setPrev(node.prev);
    node.prev.setNext(node.next);
    size--;
    return node.getElement();
}

private Optional<Node> find(E element) {
    for (Node node = header.next; node != trailer; node = node.next) {
        if (node.element == element) {
            return Optional.of(node);
        }
    }
    return Optional.empty();
}

public boolean remove(E e) {
    Optional<Node> nodeOpt = find(e);
    nodeOpt.ifPresent(n -> removeNode(n));
    return nodeOpt.isPresent();
}

The same for an insertBefore(E), insertAfter(E).

  • Related