Linear list :
Each element has a unique successor.
Two approaches to implement a linear list
Array:
Inefficient when element needs to be inserted or deleted.
Linked list:
Efficient when element needs to be inserted or deleted.
One disadvantage of using arrays to store data is that arrays are static structures and therefore cannot be easily extended or reduced to fit the data set .
con..
Arrays are also expensive to maintain new insertions and deletions.
In this chapter we consider another data structure called Linked Lists that addresses some of the limitations of arrays.
con..
A linked list, in its simplest form, is a collection of nodes that together form a linear ordering.
Each node is an object that stores a reference to an element and a reference, called next, point to another node.
con..
The order of the nodes is determined by the address, called the link, stored in each node
Every node (except the last node) contains the address of the next node
Components of a node :
Data: stores the relevant information
Link: stores the address of the next node
Structure of a node:
Data link
con..
A node with one data field number
A node with three data fields name id grdPts
A structure in a node name Home_Address phone
Head or first :
Holds the address of the first node in the list
The info part of the node can be either a value of a primitive type or a reference to an object
con..
}
Class Node
Represents nodes on a list
It has two instance variables
- info (of type int, but it can be any other type)
- link (of type Node) public class Node { public int info; public Node link;
Linked List: Some Properties
Linked list with four nodes
Linked List: Some Properties
Now consider the statement current = head;
Linked list after current = head; executes
Linked List: Some Properties
Now consider the statement
current = current.link;
List after the statement current = current.link;
Linked List: Some Properties
Insertion
Deletion
Traversal
Traversing a Linked List
Basic operations of a linked list that require the link to be traversed
Search the list for an item
Insert an item in the list
Delete an item from the list
You cannot use head to traverse the list
You would lose the nodes of the list
Use another reference variable of the same type as head: current
Traversing a Linked List con..
The following code traverses the list current = head; while (current != null) {
//Process current current = current.link;
Three steps :
Allocate memory for the new node and insert data.
Point the new node to its successor.
Point the new node’s predecessor to the new node
Three cases:
Insert into an empty list
Insert at beginning
Insert at middle
Insert at end.
The list is empty if the head points to null.
When using a singly linked list, we can easily insert an element at the head of the list.
The main idea is that we create a new node, set its next link to refer to the same object as head, and then set head to point to the new node.
con..
Insertion of an element at the head of a singly linked list
(a) before the insertion.
(b) creation of a new node.
(c) after the insertion.
Inserting a new node v at the beginning of a singly linked list.
Note that this method works even if the list is empty.
we set the next pointer for the new node v before we make variable head point to v .
Consider the following linked list
You want to create a new node with info 50 and insert it after p
con..
The following statements create and store 50 in the info field of a new node
Node newNode = new Node(); //create newNode newNode.info = 50; //store 50 in the new node
Create newNode and store 50 in it
con..
The following statements insert the node in the linked list at the required place newNode.link = p.link; p.link = newNode;
The sequence of statements to insert the node is very important.
con..
newNode.link = p.link; executes p.link = newNode; executes
Insertion
We can also easily insert an element at the tail of the list, provided we keep a reference to the tail node
In this case, we create a new node, assign its next reference to point to the null object, set the next reference of the tail to point to this new object, and then assign the tail reference itself to this new node.
Insertion
con..
(a) before the insertion
(b) creation of a new node
(c) after the insertion.
Note that:
we set the next link for the tail in (b) before we assign the tail variable to point to the new node in
(c).
Insertion
Inserting a new node at the end of a singly linked list. This method works also if the list is empty. Note that we set the next pointer for the old tail node before we make variable tail point to the new node.
The reverse operation of inserting a new element at the head of a linked list remove an element at the head.
This operation is illustrated in removal of an element at the head of a singly linked list
(a) before the removal
(b) "linking out" the old new node
(c) after the removal.
Algorithm of Removing the node from the beginning of a singly linked list
Unfortunately, we cannot easily delete the tail node of a singly linked list.
Even if we have a tail reference directly to the last node of the list, we must be able to access the node before the last node in order to remove the last node.
But we can not reach the node before the tail by following next links from the tail.
The only way to access this node is to start from the head of the list and search all the way through the list.
But such a sequence of link hopping operations could take a long time.
As we saw in the previous section, , removing an element at the tail of a singly linked list is not easy.
Indeed, it is time consuming to remove any node other than the head since we do not have a quick way of accessing the node in front of the one we want to remove we do not have quick access to such a predecessor node.
For such applications, it would be nice to have a way of going both directions in a linked list.
(con….)
There is a type of linked list that allows us to go in both directions - forward and reverse in a linked list
It is the doubly linked list. Such lists allow for a great variety of quick update operations, including insertion and removal at both ends, and in the middle.
A node in a doubly linked list stores two references—a next link which points to the next node in the list, and a prev link, which points to the previous node in the list.
•
A doubly linked list with sentinels, header and trailer .
• An empty list would have these sentinels pointing to each other.
Adding an element at the front
we can easily perform an insertion of a new element at the beginning of a doubly linked list
Algorithm of Inserting a new node v at the beginning of a doubly linked list.
Variable size keeps track of the current number of elements in the list.
Note that this method works also on an empty list.
They also are convenient for maintaining a list of elements while allowing for insertion and removal in the middle of the list.
Given a node v of a doubly linked list (which could be possibly the header but not the trailer)
we can easily insert a new node z immediately after v. Specifically, let w the be node following v.
We execute the following steps:
Algorithm of Inserting a new node z after a given node v in a doubly linked list.
1.
2.
3.
4.
make z's prev link refer to v make z's next link refer to w make w's prev link refer to z make v's next link refer to z
Removal in the Middle of a Doubly Linked List
(a) before the removal
(b) linking out the old node
(c) after the removal (and garbage collection).
This method works even if v is the first, last, or only nonsentinel node.
Same as single linked list
Last node link is connected to the first.
When insert/ delete at the last node
Make sure to update the link field of the last node to the first node.
Circular linked list with more than one node
It is convenient to make first point to the last node
Insert a node at the front of CLL
Insert a node at the end of CLL