Reputation: 3692
I was writing an implementation of a doubly linked list in java, according to the book I'm reading. While I've got the logic pretty good so far, I had two questions which the book does not cover. My doubt is in the method which deletes a specific link(node) from the list[whose data (int
) field matches the key passed in to the method].
My questions are:
first
link in the list, why isn't the next
node's previous
field being set to null
, as the next
node will now be the first node in the link, and therefore will not refer to anything through previous
? What I mean is: current.next.previous = null
last
one in the link, why isn't the previous
node's next
link set to null
? This new node will be the last in the list, so obviously it won't refer to any other link through next
. I mean: current.previous.next = null
Here's my complete implementation, please excuse the abundant comments,I just like to keep track of what I'm doing.
package Chap_5;
/**
* Created by Manish on 10/25/2015.
* this is an implementation of a doubly linked list, it differs from a singly linked list in that you can traverse
* backwards along the list. For this, every Link(node) in the list has a reference to the previous link called previous
* Insertion routine has 3 methods - insertFirst(), insertLast() and insertAfter() which allows you to insert a node
* at the beginning, at the end or after a specific item in the list
* Deletion routine has 3 methods - deleteFirst(), deleteLast() and deleteKey(). the deleteKey() method allows to look
* up a specific node and then delete it.
* this doubly linked list is also a double ended list in that it always keeps a reference to the last node in the list
* (along with the firs)
*/
class Link3 {
//fields - int and 2 references to next and previous
public int iData;
public Link3 next;
public Link3 previous;
//constructor - initialize data and references are set to null auto.
public Link3(int data) {
iData = data;
}
//display the current link's data
public void displayLink() {
System.out.print("{" + iData + "} ");
}
}
class DoublyLinkedList {
//store 2 refernces to first and last link in list;
private Link3 first;
private Link3 last;
//constructor to set references to null
public DoublyLinkedList() {
first = null;
last = null;
}
//------------------------------------------------------------------
//isEmpty() to check if list is empty
public boolean isEmpty() {
return (first == null);
}
//------------------------------------------------------------------
//----------------INSERTION ROUTINES--------------
//------------------------------------------------------------------
//insertFirst() - to insert a node at the beginning of the list
public void insertFirst(int data) {
/**
* inserts a link with given data at the front of the list
*/
//create new link with data
Link3 newLink = new Link3(data);
//special case - if list is empty, set last accordingly
if(isEmpty()) {
last = newLink;
}
else {
//else if list !empty, connect current first link's previous field to newlink
first.previous = newLink;
}
//set next field of newlink to refer to old first
newLink.next = first;
//and set newlink as current first
first = newLink;
}
//------------------------------------------------------------------
//method to insert at last of list
public void insertLast(int data) {
/**
* inserts a link with given data at the end of linked list
*/
//create new link with data
Link3 newLink = new Link3(data);
//special case - if list is empty
if(isEmpty()) {
first = newLink;
}
else {
//if list not empty, make the current last's next refer to newlink
last.next = newLink;
//and set newlink's previous to current last
newLink.previous = last;
}
//finally set last as newlink
last = newLink;
}
//------------------------------------------------------------------
//method to insert at end of a specific link
public boolean insertAfter(int key, int data) {
/**
* inserts a link with given data after the link whose data matches given key
*/
//first search for link with given key, starting at beginning
Link3 current = first;
//until key with data is found
while(current.iData != key) {
current = current.next;
//if end of list is reached without given key, exit
if(current == null) {
return false;
}
}
//when link with key is found, create new link with data to be inserted after it
Link3 newLink = new Link3(data);
//if current link is the last one in the list
if(current == last) {
newLink.next = null;
last = newLink;
}
//else if current link is not last one in the list
else {
//first modify the links towards the right
//make the newlink's next field refer to current link's next field ie: following node
newLink.next = current.next;
//make the following node's previous field refer to newlink
//NOTE: current.next.previous refers to the previous field of the link referred to by next field of the current link
current.next.previous = newLink;
}
//then modify the links on the left
//make newlink's previous field refer to current
newLink.previous = current;
//make current's next refer to newlink
current.next = newLink;
//return status of insertion
return true;
}
//------------------------------------------------------------------
//----------------DELETION ROUTINES--------------
//------------------------------------------------------------------
public Link3 deleteFirst() {
/**
* deletes first node from the linked list
*/
//create link to be returned
Link3 temp = first;
//special case: if only 1 link in list
if(first.next == null) {
//set last as null as there will be no more links in list
last = null;
}
//else if not just 1 link in next
else {
//set following node(after first)'s previous field to null as this will be the new first
first.next.previous = null;
}
first = first.next;
//and return deleted link
return temp;
}
//------------------------------------------------------------------
public Link3 deleteLast() {
/**
* deletes last link from the linked list
*/
//create link to be deleted
Link3 temp = last;
//special case - if only 1 link in list
if(first.next == null) {
//set first to null as no links in list anymore
first = null;
}
else {
//set current second last's next field to null as this is now the new last
last.previous.next = null;
}
//and make the second last link as the new last
last = last.previous;
//and return deleted link
return temp;
}
//------------------------------------------------------------------
public Link3 deleteKey(int key){
/**
* deletes link with given data, if found
*/
//start searching for link from the first
Link3 current = first;
while (current.iData != key) {
//move forward until link found
current = current.next;
if (current == null) {
//if not found, return null
return null;
}
}
//when link found, adjust connections accordingly
//special case 1 - if this is the first link
if(current == first) {
//set new first as the first's next link
first = current.next;
}
else {
//if this is not the first link
// set preceeding link's next to refer to following link by current's next
current.previous.next = current.next;
}
//special case 2 - if this is the last link
if(current == last) {
//set new last as the current last's previous link
last = current.previous;
}
else {
//set current link's next link's previous field to refer to current link's preceeding link
current.next.previous = current.previous;
}
return current;
}
//------------------------------------------------------------------
//----------TRAVERSAL ROUTINES----------
//------------------------------------------------------------------
public void displayForward() {
/**
* display links forward ie: left -> right
*/
System.out.println("List (first -> last)");
//start at first and move forward
Link3 current = first;
while (current != null) {
current.displayLink();
//change current to refer to following node
current = current.next;
}
System.out.println(" ");
}
//------------------------------------------------------------------
public void displayBackward() {
/**
* display links backward ie: right -> left
*/
System.out.println("List (last -> first)");
//start at last and move backward
Link3 current = last;
while (current != null) {
current.displayLink();
//change current to refer to previous node
current = current.previous;
}
System.out.println(" ");
}
}
public class DoublyLinkedApp {
public static void main(String[] args) {
//create new list
DoublyLinkedList theList = new DoublyLinkedList();
//insert 3 at front
theList.insertFirst(22);
theList.insertFirst(44);
theList.insertFirst(66);
//insert 3 items at end
theList.insertLast(11);
theList.insertLast(33);
theList.insertLast(55);
//display list forward
theList.displayForward();
//display list backward
theList.displayBackward();
//delete first item
System.out.println("Deleted: " + theList.deleteFirst().iData);
//delete last item
System.out.println("Deleted: " + theList.deleteLast().iData);
//delete a specific link - with key 11
System.out.println("Deleted: " + theList.deleteKey(11).iData);
//display list forward again
theList.displayForward();
//insert 2 items after a specific link
//insert after link with data 22
theList.insertAfter(22, 77);
theList.displayForward();
//insert after link with 33
theList.insertAfter(33, 89);
theList.displayForward();
}
}
Upvotes: 1
Views: 94
Reputation: 691695
When the link to be deleted turns out to be the first link in the list, why isn't the next node's previous field being set to null
It is set to null by this instruction:
current.next.previous = current.previous;
Indeed, if current is the first node, current.previous
is null, and the next node's previous is thus set to null by being set to current.previous
.
The same goes for the last node's next, which is set to null by
current.previous.next = current.next;
Upvotes: 1