Describe and implement a singly-linked list in Java.
A Linked List is a collection of nodes (implemented as a class – see below at Node.java) where each node is connected to the next node by reference (address).
Each node is implemented as a class containing two private variables
- Data value (could be a String/integer/double/another class)
- Reference value of the next node
Unlike an array, where each cell had a specific cell number and could be accessed independent of other cells, access to a node (say, X) in a linked list is dependent on having a reference to the previous node (say, Y).
public class Node {
// Setting instance variables as private means only the containing class
// (in this case, Node) can access them directly. Outside classes need
// to use the 'getter' and 'setter' methods implemented below.
private int data;
private Node next;
// The constructor. This method creates a new Node with some int data 'value'
// and some next Node reference 'ref'
public Node(int value, Node ref) {
data = value;
next = ref;
}
// 'Getter' method for the data. Since only a getter method
// is defined for 'data', it is considered read-only or immutable.
public int getData() {
return data;
}
// 'Getter' method for the next Node
public Node getNextReference() {
return next;
}
// 'Setter' method for the next Node. Since both a setter
// and a getter method are defined, the instance variable
// 'next' is considered read/write or mutable.
public void setNextReference(Node value) {
next = value;
}
// Allows us to println references and be human-readable
public String toString()
{
String data = String.valueOf(this.data);
return "Data: " + data;
}
}
public class LinkedList {
// References to the beginning (head) and end (tail)
// of the list
private Node head;
private Node tail;
// No-argument constructor. When we make a new list,
// it is empty, so both instance variables are set
// to null, or nothing
public LinkedList() {
head = null;
tail = null;
}
// Example:
// If the list is 1->2->3, then list.insertAtBack(4) gives us
// 1->2->3->4
public void insertAtBack(int word) {
// Only if we have a new, empty list. We need to set the head
// of the list. Since there is only one element in the list,
// that element is both the head and tail.
if (head == null) {
head = new Node(word, null);
tail = head;
}
// Otherwise, we do not have an empty List. We first save
// the current tail in a temporary variable. Then, the
// tail is updated to a new node with the given data, and
// then the previous tail's next reference to the new tail
else {
Node tempref = tail;
tail = new Node(word, null);
tempref.setNextReference(tail);
}
}
public void printList() {
// We assume that the head is only null if the list is empty
if (head == null) {
System.out.println ("The List is Empty");
}
// Otherwise, we need to traverse the list
else {
// Setting a temporary variable to the head of the list
// is necessary to traverse the list, and not lose the
// reference to the beginning
Node tempref = head;
System.out.println("The values so far in the list : ");
// If tempref is null, we're at the end of the list
while (tempref != null) {
// Print the data
System.out.print(tempref.getData());
// Move along the list
tempref = tempref.getNextReference();
// If we have another Node, and therefore are not
// at the end, print a connecting arrow.
if (tempref != null) {
System.out.print (" --> ");
}
}
System.out.println("\n");
}
}
}
import java.util.Scanner;
public class LinkedListTest {
// Prints a helpful menu for the user
public static void Menu() {
System.out.println("1 - Insert At Back ");
System.out.println("2 - Quit");
}
public static void main(String[] args) {
System.out.println("Linked Lists");
// Two Scanner objects are required, due to a Java quirk
// in how streams are scanned.
Scanner scanner = new Scanner(System.in);
Scanner scanner1 = new Scanner(System.in);
int choice = 0, status = 0, entry = 0;
boolean flag = true;
LinkedList list = new LinkedList();
while (flag) {
// Print the menu
Menu();
status = 0;
// try-catch statements prevent Java Exceptions, or
// runtime errors. The Integer.parseInt() method can
// returned either the parsed integer, or causes an
// Exception if it is not a number. This Exception is
// 'caught' with the catch statement. By defining the
// Exception object as the generic 'Exception' type,
// it will catch all Exceptions that are subclasses of
// Exception, or all built-in Exceptions.
try {
choice = Integer.parseInt(scanner.nextLine());
}
catch (Exception e) {
System.out.println("Integers Only - Enter Again");
status = 1;
}
// The user chose to add a value to the list
if (choice == 1) {
System.out.println ("Enter the value?");
entry = scanner1.nextInt();
list.insertAtBack(entry);
}
// The user chose to end the program
else if (choice == 2) {
flag = false;
System.out.println ("End of Program");
}
// The user entered a number that was not a legal menu
// option, but still parsable by Integer.parseInt()
else if (status == 0) {
System.out.println ("Invalid Entry - Enter Again");
}
// Print the list after every entered value
list.printList();
}
}
}
Linked Lists
1 - Insert At Back
2 - Quit
> what
Integers Only - Enter Again
The List is Empty
1 - Insert At Back
2 - Quit
> 34
Invalid entry - Choose from menu
The List is Empty
1 - Insert At Back
2 - Quit
> 1
Enter the value?
> 90
The values so far in the list:
90
1 - Insert At Back
2 - Quit
> 1
Enter the value?
> 789
The values so far in the list:
90 --> 789
1 - Insert At Back
2 - Quit
> 1
Enter the value?
> 678
The values so far in the list:
90 --> 789 --> 678
1 - Insert At Back
2 - Quit
> 2
End of Program
The values so far in the list:
90 --> 789 --> 678
Add the following methods to the Linked List
isEmpty(), which returns true if the list is empty and false if the list is not empty.insertAtFront(int input), which inserts the input value at the front of the list.removeFromFront(), which removes the front value of the list.removeFromBack(), which removes the tail value of the list.Remains the same
public class LinkedList {
private Node head;
private Node tail;
public LinkedList() {
head = null;
tail = null;
}
public void insertAtBack(int num) {
if (head == null) {
head = new Node(num, null);
tail = head;
} else {
Node tempref = tail;
tail = new Node (num, null);
tempref.setNextReference(tail);
}
}
public void insertAtFront (int num) {
if (head == null) {
head = new Node(num, null);
tail = head;
} else {
Node tempref = new Node(num, head);
head = tempref;
}
}
public boolean isEmpty() {
return head == null;
}
public void removeFromFront() {
if (head == null) {
System.out.println ("List is Empty");
} else {
head = head.getNextReference();
}
}
public void removeFromBack() {
if (this.isEmpty()) {
System.out.println("The list is empty.");
} else if (head == tail) {
head = null;
tail = head;
} else {
Node prev = head;
Node curr = head;
while (curr != tail) {
prev = curr;
curr = curr.getNextReference();
}
prev.setNextReference(null);
tail = prev;
}
}
public void printList() {
if (head == null) {
System.out.println ("The List is Empty");
}
else {
Node tempref = head;
System.out.println("The values so far in the list : ");
while (tempref != null) {
System.out.print(tempref.getData());
tempref = tempref.getNextReference();
if (tempref != null) {
System.out.print (" --> ");
}
}
System.out.println("\n");
}
}
}
import java.util.Scanner;
public class LinkedListTest {
public static void Menu() {
System.out.println("1 - Insert At Back ");
System.out.println("2 - Insert At Front");
System.out.println("3- Remove From Front");
System.out.println("4- Remove From Back");
System.out.println("5 - Quit");
}
public static void main (String[] args) {
System.out.println("Linked Lists");
Scanner scanner = new Scanner(System.in);
Scanner scanner1 = new Scanner(System.in);
int choice = 0, status = 0, entry = 0;
boolean flag = true;
LinkedList list = new LinkedList();
while (flag) {
Menu();
status = 0;
try {
choice = Integer.parseInt(scanner.nextLine());
} catch (Exception e) {
System.out.println("Integers Only - Enter Again");
status = 1;
}
if (choice == 1) {
System.out.println("Enter the value?");
entry = scanner1.nextInt();
list.insertAtBack(entry);
} else if (choice == 2) {
System.out.println("Enter the value?");
entry = scanner1.nextInt();
list.insertAtFront(entry);
} else if (choice == 3) {
list.removeFromFront();
} else if (choice == 4) {
list.removeFromBack();
} else if (choice == 5) {
flag = false;
System.out.println("End of Program");
} else if (status == 0) {
System.out.println("Invalid Entry - Choose From Menu");
}
list.printList();
}
}
}
Linked Lists
1 - Insert At Back
2 - Insert At Front
3 - Remove From Front
4 - Remove From Back
5 - Quit
> 1
Enter the value?
> 34
The values so far in the list :
34
1 - Insert At Back
2 - Insert At Front
3 - Remove From Front
4 - Remove From Back
5 - Quit
> 2
Enter the value?
> 12
The values so far in the list :
12 --> 34
1 - Insert At Back
2 - Insert At Front
3 - Remove From Front
4 - Remove From Back
5 - Quit
> 2
Enter the value?
> 134
The values so far in the list :
134 --> 12 --> 34
1 - Insert At Back
2 - Insert At Front
3 - Remove From Front
4 - Remove From Back
5 - Quit
> 3
The values so far in the list :
12 --> 34
1 - Insert At Back
2 - Insert At Front
3 - Remove From Front
4 - Remove From Back
5 - Quit
> 4
The values so far in the list :
12
1 - Insert At Back
2 - Insert At Front
3 - Remove From Front
4 - Remove From Back
5 - Quit
> 3
The List is Empty
1 - Insert At Back
2 - Insert At Front
3 - Remove From Front
4 - Remove From Back
5 - Quit
> 5
End of Program
The List is Empty
Add an additional choice in the Menu for Problem #1 which does the following:
Remains the same
public class LinkedList {
// The previous linked list code stays the same
public int getMaxValue() {
Node tempRef = head;
int max = Integer.MIN_VALUE;
while (tempRef != null) {
int value = tempRef.getData();
if (value > max) {
max = value;
}
tempRef = tempRef.getNextReference();
}
return max;
}
public Node getMaxReference() {
Node tempRef = head;
int max = this.getMaxValue();
if (this.isEmpty()) {
return null;
}
while (tempRef.getData() != max) {
tempRef = tempRef.getNextReference();
}
return tempRef;
}
// inserts the maximum value to the end of the list
public void maxToBack() {
if (head != null) {
int max = getMaxValue();
Node maxad = getMaxReference(max);
if (head != tail) {
if (head == maxad) {
removeFromFront();
insertAtBack(max);
} else if (tail != maxad) {
Node curr = head;
Node prev = head;
while (curr != maxad) {
prev = curr;
curr = curr.getNextReference();
}
prev.setNextReference(curr.getNextReference());
insertAtBack(max);
}
}
}
}
}
Add the new choices as demonstrated in Problem 2.
Linked Lists
1 - Insert At Back
2 - Insert At Front
3- Remove From Front
4- Remove From Back
5 - Max to Back
6 - Quit
> 1
Enter the value?
> 45
The values so far in the list :
45
1 - Insert At Back
2 - Insert At Front
3- Remove From Front
4- Remove From Back
5 - Max to Back
6 - Quit
> 5
The values so far in the list :
45
1 - Insert At Back
2 - Insert At Front
3- Remove From Front
4- Remove From Back
5 - Max to Back
6 - Quit
> 2
Enter the value?
> 908
The values so far in the list :
908 --> 45
1 - Insert At Back
2 - Insert At Front
3- Remove From Front
4- Remove From Back
5 - Max to Back
6 - Quit
> 5
The values so far in the list :
45 --> 908
1 - Insert At Back
2 - Insert At Front
3- Remove From Front
4- Remove From Back
5 - Max to Back
6 - Quit
> 1
Enter the value?
> 1900
The values so far in the list :
45 --> 908 --> 1900
1 - Insert At Back
2 - Insert At Front
3- Remove From Front
4- Remove From Back
5 - Max to Back
6 - Quit
> 5
The values so far in the list :
45 --> 1900 --> 908
1 - Insert At Back
2 - Insert At Front
3- Remove From Front
4- Remove From Back
5 - Max to Back
6 - Quit
> 1
Enter the value?
> 999
The values so far in the list :
45 --> 1900 --> 908 --> 999
1 - Insert At Back
2 - Insert At Front
3- Remove From Front
4- Remove From Back
5 - Max to Back
6 - Quit
> 5
The values so far in the list :
45 --> 1900 --> 908 --> 999
1 - Insert At Back
2 - Insert At Front
3- Remove From Front
4- Remove From Back
5 - Max to Back
6 - Quit
> 2
Enter the value?
9999
The values so far in the list :
9999 --> 45 --> 1900 --> 908 --> 999
1 - Insert At Back
2 - Insert At Front
3- Remove From Front
4- Remove From Back
5 - Max to Back
6 - Quit
> 5
The values so far in the list :
45 --> 1900 --> 908 --> 999 --> 9999
1 - Insert At Back
2 - Insert At Front
3- Remove From Front
4- Remove From Back
5 - Max to Back
6 - Quit
> 6
End of Program
The values so far in the list :
45 --> 1900 --> 908 --> 999 --> 9999