Professional Documents
Culture Documents
A linked list is a linear data structure where each element is a separate object. Each element
(we will call it a node) of a list is comprising of two items - the data and a reference to the
next node. The last node has a reference to null. The entry point into a linked list is called
the head of the list. It should be noted that head is not a separate node, but the reference to the
first node. If the list is empty then the head is a null reference.
A linked list is a dynamic data structure. The number of nodes in a list is not fixed and can
grow and shrink on demand. Any application which has to deal with an unknown number of
objects will need to use a linked list.
One disadvantage of a linked list against an array is that it does not allow direct access to the
individual elements. If you want to access a particular item then you have to start at the head
and follow the references until you get to that item.
Another disadvantage is that a linked list uses more memory compare with an array
1
Collected by Bipin Timalsina
DSA with Java/Unit-2
A linked list is a data structure used for storing collections of data. A linked list has the
following properties.
Successive elements are connected by pointers
The last element points to NULL
Can grow or shrink in size during execution of a program
Can be made just as long as required (until systems memory exhausts)
2
Collected by Bipin Timalsina
DSA with Java/Unit-2
In Java, singly linked list can be represented as a class and a Node as a separate class. The
SingLinkedList class contains a reference of Node class type.
//node structure
class Node {
int data;
Node next;
}
class SingLinkedList {
Node head;
//constructor to create an empty SingLinkedList
SingLinkedList(){
head = null;
}
}
Insertion
Insertion into a singly linked list has three cases:
Inserting a new node before the head (at the beginning)
Inserting a new node after the tail (at the end of the list)
Inserting a new node at the middle of the list (random location)
Note: To insert an element in the linked list at some position p, assume that after inserting the
element the position of this new node is p.
3
Collected by Bipin Timalsina
DSA with Java/Unit-2
1. Update the next pointer of new node, to point to the current head
Following method in Java can insert new node to beginning of Singly Linked List
void insertAtBegining(int newElement) {
//1. allocate a new node
Node newNode = new Node();
//2. assign data element
newNode.data = newElement;
//3. make next node of new node as head
newNode.next = head;
//4. make new node as head
head = newNode;
}
4
Collected by Bipin Timalsina
DSA with Java/Unit-2
Following method in Java can insert a node at ending of Singly Linked List
5
Collected by Bipin Timalsina
DSA with Java/Unit-2
Time Complexity: O(n), since, in the worst case, we may need to insert the node at the end of the
list.
Space Complexity: O(1), for creating one temporary variable.
Following method in Java can insert a node at given position in Singly Linked List
void insertAtPosition(int newElement, int position) {
7
Collected by Bipin Timalsina
DSA with Java/Unit-2
8
Collected by Bipin Timalsina
DSA with Java/Unit-2
Deletion
Similar to insertion, here we also have three cases.
Deleting the first node
Deleting the last node
Deleting an intermediate node.
Deleting the First Node in Singly Linked List
First node (current head node) is removed from the list. It can be done in two steps:
1. Create a temporary node which will point to the same node as that of head.
2. Now, move the head nodes pointer to the next node and dispose of the temporary node.
Following method in Java can delete the first node in Singly Linked List:
void delFirst() {
if(this.head != null) {
9
Collected by Bipin Timalsina
DSA with Java/Unit-2
10
Collected by Bipin Timalsina
DSA with Java/Unit-2
Following method in Java can delete the last node in singly Linked List
void delLast() {
if(this.head != null) {
//1. if head in not null and next of head
// is null, release the head
if(this.head.next == null) {
this.head = null;
} else {
//2. Else, traverse to the second last
// element of the list
Node temp = new Node();
temp = this.head;
while(temp.next.next != null)
temp = temp.next;
11
Collected by Bipin Timalsina
DSA with Java/Unit-2
Time Complexity: O(n). In the worst case, we may need to delete the node at the end of the list.
Space Complexity: O(1). Since, we are creating only one temporary variable.
Following method in Java can delete the node at given position in Singly Linked List:
12
Collected by Bipin Timalsina
DSA with Java/Unit-2
13
Collected by Bipin Timalsina
DSA with Java/Unit-2
Search
The insertion and deletion operations modify linked lists. The searching operation scans an
existing list to learn whether an element is in it. To search any value in the singly linked list, we
can traverse the linked list and compares the value present in the node.
boolean searchSLL(Node head, int val)
{
// creating a temp variable pointing to the head of the linked list
Node temp = head
while( temp != NULL) // traversing the list
{
if( temp.data == val )
return true
temp = temp.next
}
return false
}
The advantage of a doubly linked list (also called two – way linked list) is that given a node in
the list, we can navigate in both directions. A node in a singly linked list cannot be removed unless
we have the pointer to its predecessor. But in a doubly linked list, we can delete a node even if we
14
Collected by Bipin Timalsina
DSA with Java/Unit-2
don’t have the previous node’s address (since each node has a left pointer pointing to the previous
node and can move backward).
The primary disadvantages of doubly linked lists are:
o Each node requires an extra pointer, requiring more space.
o The insertion or deletion of a node takes a bit longer (more pointer operations).
In Java, doubly linked list can be represented as a class and a Node as a separate class. The
DoubLinkedList class contains a reference of Node class type.
//node structure
class Node {
int data;
Node next;
Node prev;
}
class DoubLinkedList {
Node head;
//constructor to create an empty DoubLinkedList
DoubLinkedList(){
head = null;
}
}
Doubly Linked List Insertion
Insertion into a doubly-linked list has three cases (same as a singly linked list).
Inserting a new node before the head.
Inserting a new node after the tail (at the end of the list).
Inserting a new node at the middle of the list.
Inserting a Node in Doubly Linked List at the Beginning
In this case, new node is inserted before the head node. Previous and next pointers need to be
modified and it can be done in two steps:
15
Collected by Bipin Timalsina
DSA with Java/Unit-2
1. Update the right pointer of the new node to point to the current head node (dotted link
in below figure) and also make left pointer of new node as NULL.
2. Update head node’s left pointer to point to the new node and make new node as head.
Following method in Java can insert new node to beginning of Doubly Linked List
16
Collected by Bipin Timalsina
DSA with Java/Unit-2
17
Collected by Bipin Timalsina
DSA with Java/Unit-2
Following method in Java can insert a node at ending of Doubly Linked List
void insertAtEnding(int newElement) {
18
Collected by Bipin Timalsina
DSA with Java/Unit-2
2. Position node right pointer points to the new node and the next node of position node left
pointer points to new node.
Time Complexity: O(n). In the worst case, we may need to insert the node at the end of the list.
Space Complexity: O(1), for creating one temporary variable.
19
Collected by Bipin Timalsina
DSA with Java/Unit-2
Following method in Java can insert a node at given position in Doubly Linked List
void insertAtPosition(int newElement, int position) {
20
Collected by Bipin Timalsina
DSA with Java/Unit-2
if(temp != null) {
newNode.next = temp.next;
newNode.prev = temp;
temp.next = newNode;
if(newNode.next != null)
newNode.next.prev = newNode;
} else {
2. Now, move the head nodes pointer to the next node and change the heads left pointer to
NULL and dispose of the temporary node.
21
Collected by Bipin Timalsina
DSA with Java/Unit-2
Following method in Java can delete the first node in Doubly Linked List:
void delFirst() {
if(this.head != null) {
22
Collected by Bipin Timalsina
DSA with Java/Unit-2
2. Update the next pointer of previous node to the tail node with NULL.
23
Collected by Bipin Timalsina
DSA with Java/Unit-2
Following method in Java can delete the last node in Doubly Linked List
void delLast() {
if(this.head != null) {
24
Collected by Bipin Timalsina
DSA with Java/Unit-2
Following method in Java can delete the node at given position in Doubly Linked List:
25
Collected by Bipin Timalsina
DSA with Java/Unit-2
26
Collected by Bipin Timalsina
DSA with Java/Unit-2
nodeToDelete = null;
nextNodeFromNodeToDelete.prev = temp;
} else {
Circular Lists
A circular singly linked list can be visualized as a chain of nodes, where every node points
to the next node. Along with this, next of the last node is linked to the head node.
.
In a circular linked list, we access the elements using the head node (similar to head node
in singly linked list and doubly linked lists).
In singly linked lists and doubly linked lists, the end of lists are indicated with NULL value.
But circular linked lists do not have ends.
While traversing the circular linked lists we should be careful; otherwise we will be
traversing the list infinitely.
In circular linked lists, each node has a successor. Note that unlike singly linked lists, there
is no node with NULL pointer in a circularly linked list.
27
Collected by Bipin Timalsina
DSA with Java/Unit-2
In some situations, circular linked lists are useful. For example, when several processes are
using the same computer resource (CPU) for the same amount of time, we have to assure
that no process accesses the resource before all other processes do (round robin algorithm).
In Java, circular linked list can be represented as a class and a Node as a separate class. The
CircLinkedList class contains a reference of Node class type.
//node structure
class Node {
int data;
Node next;
}
class CircLinkedList {
Node head;
//constructor to create an empty CircLinkedList
CircLinkedList(){
head = null;
}
}
Counting nodes in a Circular Linked List
The circular list is accessible through the node marked head. (also called tail). To count the nodes,
the list has to be traversed from the node marked head, with the help of a dummy node current,
and stop the counting when current reaches the starting node head. If the list is empty, head will
be NULL, and in that case set count = 0. Otherwise, set the current pointer to the first node, and
keep on counting till the current pointer reaches the starting node.
28
Collected by Bipin Timalsina
DSA with Java/Unit-2
2. Update the next pointer of the new node with the head node and also traverse the list to the
tail. That means in a circular list we should stop at the node whose next node is head.
29
Collected by Bipin Timalsina
DSA with Java/Unit-2
3. Update the next pointer of the previous node to point to the new node and we get the list
as shown below.
Following method in Java can insert a node at ending of Circular Linked List
30
Collected by Bipin Timalsina
DSA with Java/Unit-2
31
Collected by Bipin Timalsina
DSA with Java/Unit-2
Update the next pointer of the new node with the head node and also traverse the list until the
tail. That means in a circular list we should stop at the node which is its previous node in the
list.
32
Collected by Bipin Timalsina
DSA with Java/Unit-2
Time Complexity: O(n), for scanning the complete list of size n. Space Complexity: O(1), for
temporary variable.
Following method in Java can insert a node at beginning of Circular Linked List
head = newNode;
}
}
34
Collected by Bipin Timalsina
DSA with Java/Unit-2
35
Collected by Bipin Timalsina
DSA with Java/Unit-2
Create a temporary node which will point to the head. Also, update the tail nodes next
pointer to point to next node of head (as shown below).
36
Collected by Bipin Timalsina
DSA with Java/Unit-2
Now, move the head pointer to next node. Create a temporary node which will point to
head. Also, update the tail nodes next pointer to point to next node of head (as shown
below).
Java method:
void delFirst() {
if(this.head != null) {
37
Collected by Bipin Timalsina
DSA with Java/Unit-2
temp = temp.next;
}
The first node also known as HEAD is always used as a reference to traverse the list. Last element
contains link to the first element as next and the first element contains link of the last element as
38
Collected by Bipin Timalsina
DSA with Java/Unit-2
previous. A circular doubly linked can be visualized as a chain of nodes, where every node points
to previous and next node.
Skip Lists
Linked lists have one serious drawback: They require sequential scanning to locate a searched-
for element. The search starts from the beginning of the list and stops when either a searched-for
element is found or the end of the list is reached without finding this element. Ordering elements
on the list can speed up searching, but a sequential search is still required. Therefore, we may think
about lists that allow for skipping certain nodes to avoid sequential processing. A skip list is an
interesting variant of the ordered linked list that makes such a nonsequential search possible.
In an ordinary sorted linked list, search, insert, and delete are in O(n) because the list must be
scanned node-by-node from the head to find the relevant node. If somehow we could scan down
the list in bigger steps (skip down, as it were), we would reduce the cost of scanning. This is the
fundamental idea behind Skip Lists.
A skip list is a data structure that is used for storing a sorted list of items with a help of hierarchy
of linked lists that connect increasingly sparse subsequences of the items. A skip list allows
the process of item look up in efficient manner. The skip list data structure skips over many of
the items of the full list in one step, that’s why it is known as skip list.
A skip list is built up of layers. The lowest layer (i.e. bottom layer) is an ordinary ordered
linked list. The higher layers are like ‘express lane’ where the nodes are skipped
NOTE: A skip list is a probabilistic data structure. A skip list is built in layers. The bottom layer is
an ordinary ordered linked list. Each higher layer acts as an "express lane" for the lists below,
where an element in layer i appears in layer i+1 with some fixed probability p (two commonly
used values for pare 1/2 or 1/4)
39
Collected by Bipin Timalsina
DSA with Java/Unit-2
In a skip list of n nodes, for each k and i such that 1 ≤ k ≤ ⎣lg n⎦ and 1 ≤ i ≤ ⎣ n/2k–1 ⎦ – 1, the
node in position 2k–1 · i points to the node in position 2k–1 · (i + 1).
This means that every second node points to the node two positions ahead, every fourth node
points to the node four positions ahead, and so on.
This is accomplished by having different numbers of reference fields in nodes on the list:
Half of the nodes have just one reference field,
one-fourth of the nodes have two reference fields,
one-eighth of the nodes have three reference fields,
and so on.
The number of reference fields indicates the level of each node, and the number of levels is
maxLevel = ⎣lg n⎦ + 1
Searching for an element el consists of following the references on the highest level until an
element is found that finishes the search successfully. In the case of reaching the end of the list or
encountering an element key that is greater than el, the search is restarted from the node preceding
the one containing key, but this time starting from a reference on a lower level than before. The
search continues until el is found, or the first-level references are followed to reach the end of the
list or to find an element greater than el. Here is a pseudocode for this algorithm:
40
Collected by Bipin Timalsina
DSA with Java/Unit-2
41
Collected by Bipin Timalsina
DSA with Java/Unit-2
Self-Organizing Lists
The introduction of skip lists was motivated by the need to speed up the searching process.
Although singly and doubly linked lists require sequential search to locate an element or to see
that it is not in the list, we can improve the efficiency of the search by dynamically organizing
the list in a certain manner. This organization depends on the configuration of data; thus, the
stream of data requires reorganizing the nodes already on the list.
A self-organizing list is a list that reorders its elements based on some self-organizing heuristic to
improve average access time. The aim of a self-organizing list is to improve efficiency of linear
search by moving more frequently accessed items towards the head of the list. A self-organizing
list achieves near constant time for element access in the best case. A self-organizing list uses a
reorganizing algorithm to adapt to various query distributions at runtime.
A self-organizing list reorders its nodes based on searches which are done. The idea is to use
locality of reference (In a typical database, 80% of the access are to 20% of the items)
There are many different ways to organize the lists. Followings are some of the techniques used
by self-organizing lists:
42
Collected by Bipin Timalsina
DSA with Java/Unit-2
43
Collected by Bipin Timalsina
DSA with Java/Unit-2
2. Transpose method
After the desired element is located, swap it with its predecessor unless it is at the head
of the list
Any node searched is swapped with the preceding node. Unlike Move-to-front, this
method does not adapt quickly to changing access patterns.
If the 5th node in the list is selected, it will be swapped with the 4th
44
Collected by Bipin Timalsina
DSA with Java/Unit-2
3. Count method.
Order the list by the number of times elements are being accessed.
Each node stores count of the number of times it was searched. Nodes are ordered by
decreasing count. This strategy requires extra space for storing count.
If the 5th node in the list is searched for twice, it will be swapped with the 4th
4. Ordering method.
Order the list using certain criteria natural for the information under scrutiny.
In the first three methods, new information is stored in a node added to the end of the
list but in the Ordering method, new information is stored in a node inserted
somewhere in the list to maintain the order of the list.
The ordering method already uses some properties inherent to the information stored
in the list. For example, if we are storing nodes pertaining to people, then the list can
be organized alphabetically by the name of the person or the city or in ascending or
descending order using, say, birthday or salary.
45
Collected by Bipin Timalsina
DSA with Java/Unit-2
Figure 13: Accessing an element on a linked list and changes on the list depending
on the self-organization technique applied: (a) move-to-front method, (b) transpose
method, (c) count method, and (d) ordering method, in particular, alphabetical
ordering, which leads to no change. In the case when the desired element is not in
the list, (e) the first three methods add a new node with this element at the end of
the list and (f) the ordering method maintains an order on the list.
46
Collected by Bipin Timalsina
DSA with Java/Unit-2
Sparse Tables
In many applications, the choice of a table seems to be the most natural one, but space
considerations may preclude this choice. This is particularly true if only a small fraction of the
table is actually used. A table of this type is called a sparse table.
A sparse table refers to a table that is populated sparsely by data and most of its cells
are empty
With a sparse table, the table can be replaced by a system of linked lists
Array of linked list can be used to represent sparse table.
Case Study
LinkedList class of java.util package
Explore the LinkedList class present in java.util package. Discuss how linked list is implemented.
List the important constructors and methods present in the class with signatures and usages. Write
some Java programs to illustrate different operations like search, insertion, and deletion using the
constructors and methods present in the class.
47
Collected by Bipin Timalsina