- 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 twoEs. Remove it. addBetweenis nicely symmetric, butsuccessoris redundant. I would remove it as parameter and make it a local variable.- Rename the local variable
Nodetolist.
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).
