- This code allows me to create a linked list and I want to be able to add elements between two nodes.
- 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 twoE
s. Remove it. addBetween
is nicely symmetric, butsuccessor
is redundant. I would remove it as parameter and make it a local variable.- Rename the local variable
Node
tolist
.
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)
.