link list notes
link list notes
• Consider the RAM where the new process requires the memory. When free memory is
not available contiguously, use of linked list for linking of free memory chunks (Holes) will
serve the purpose.
• Linked List provides efficient use of memory.
• It’s a Dynamic Data Structure, which can change its size (Data Structure can grow or shrink
as per the requirement) during the program execution.
• Insertion and deletion operations are easier and efficient as compared to Array.
Definition
A Linked List is a data structure which consists of nodes. Every node contains at least two fields.
One of which contains the information and other one contains address of next node.
Properties
• A Linked List is identified through the address of the first node
• To access a node, we need to reach to that node
There are some pros and cons with each of the data structure, so too the Array. Array offers the
indexed access (fast) but have fixed size. Static array cannot grow or shrink as per the requirement.
Array size may fall short or remain under-utilized according the problem in hand. The Dynamic
Arrays, e.g. Python List, provide the variable length but the concept is based on reserving surplus
memory. Insertion of the data item at the beginning of Static or Dynamic array is costlier than
inserting the data at the tail.
Linked List, on the other hand, allocates the memory on demand and insertion and deletions are
easier as compared to Arrays.
Linear Linked List: The diagram below shows linear Linked List where each node contains
information and the address of the next node. The address field of last node contains no address
(NULL).
Circular Linked List: Circular Linked List is more like Linear Linked List except that the address
field of the last node contains the address of the first node. START keeps the address of the last
node in the circular Linked List.
Doubly Linked List: Each node in this type of the Linked List contains at 2 address fields (One for
the address of previous node and other one for the address of the next node).
Circular Doubly Linked List: Similar to Doubly Linked List except that the previous field of the first
node and next field of the last node is not NULL. Next field of the last keeps the address of the
first node and previous field of the first node keeps the address of the last node.
-
The fields are accessed as:
P→ Info
P→Next
• GetNode( ) is used for allocation of memory for new node
• START is used for keeping the address of First node. In case the Linked List is empty, START
keeps a NULL.
• Item is used to refer to the element to be inserted.
• When the nodes are deleted, their memory is freed by calling the function FreeNode( )
• For the new node, P is used to keep the address of the newly created node.
Single/Linear Linked List: The diagram below shows linear Linked List where each node contains
information and the address of the next node. The address field of last node contains no address
(NULL).
Complexity of Operation
Time Complexity = O(1)
Space Complexity = O(1)
No of link adjustment = 2
Complexity of Operation
Time Complexity = O(1)
Space Complexity = O(1)
No of Link adjustment = 2
Complexity of Operation:
Time Complexity = O(n)
Space Complexity = O(1)
Deletion in Linked List
1. Deletion from the beginning
Given a Linked List, our task is to remove the first node of the Linked List and update the head
pointer of the Linked List. To remove first node, we need to make the second node as head and
delete the memory allocated for first node.
No of address Adjustment = 1
Complexity of Operation
Time Complexity = O(1)
Space Complexity = O(1)
ALGORITHM DelAfter(START, Q)
BEGIN:
IF Q = = NULL AND Q → Next!=NULL THEN
WRITE (“Void Deletion”)
ELSE
P = Q→Next
Q→Next = P→Next
Item = P→ Item
FreeNode(P)
RETURN Item
END;
No of address adjustment = 1
Complexity of Operation:
Time Complexity = O(1)
Space Complexity = O(1)
Other Algorithms
ALGORITHM Display(P)
BEGIN:
IF P ! = NULL THEN
WRITE P→Info!=NULL DO
Display(P→Next)
End;
Complexity of Operation:
Time Complexity: O (n)
Space Complexity: O (n)
Ordered Insertion
It is an operation, which inserts an element at its correct position in a sorted Linked List.
ALGORITHM OrderedInsertion (START, Key)
BEGIN:
Q = NULL
P = START
WHILE P != NULL AND Key >= P→Info DO
Q=P
P = P→Next
IF Q != NULL THEN
InsAft(Q, Key)
ELSE
InsBeg(START, Key)
END;
Complexity of Operation
No of Address node Adjustment = 2
Time Complexity = Ω(1), O(n)
Space Complexity = O(1)
Merging
It is an approach in which we combine two sorted Linked List and generates third sorted list. Here
first list contains m nodes, second list contains n nodes and the final sorted list contains m+n
nodes.
Complexity of Operation
Time Complexity = O(m+n)
Space Complexity = O(m+n) extra space
Split List from Mid
In this method, we will traverse the list using two pointers slow pointer Q and fast pointer P. Slow
pointer will be moved by one position and fast pointer will be moved by two position.
ALGORITHM SplitMid(START)
BEGIN:
Q = START
P = START→Next
WHILE P != NULL || P→ Next != NULL DO /* IF fast pointer P points to either last
node or second last node (Q lies in the
middle)*/
Q = Q→ Next
P = P→ Next → Next
START2 = Q→ Next
Q→ Next = NULL
RETURN START2
END;
Complexity of Operation:
No of address node Adjustment = 1
Time Complexity = O(n/2) = O(n)
Space Complexity = O(1)
Union of two sorted lists
The Union of two sorted Linked List is the new Linked List which contains all the elements which
are present in at least one of the Linked Lists.
Complexity of Operation
Time Complexity = O(m+n)
Space Complexity = O(m+n) extra space
Intersection of two sorted Linked List
This algorithm performs set intersection operation on given two Linked List.
Explanation: In the above algorithm initially, there are two input Linked List. START1 has the
starting address of first Linked List and START2 has starting address of second Linked List. A
temporary pointer P1 is taken which traverses till the last node of first Linked List and P2 is taken
which traverses till the last node of second Linked List. Every Information field of first list is
compared with second and the common Information field is picked. The common Information
field is then added in third Linked List with START3 pointer using Insertend( ).
Complexity:
Time Complexity: O(m + n)
Space Complexity: O(x) where x is maximum between m and n
Difference (Set Difference) of two sorted Linked List
Considering A – B
Complexity of Operation
Time Complexity = O(m+n)
Space Complexity = O(x), x is smallest of m and n
Reverse the Linked List (In Place)
Problem: Given address to the head node of a Linked List, the task is to reverse the Linked List.
(We need to reverse the list by changing the links between nodes).
Solution
Given address of the head node of a Linked List, the task is to reverse the Linked List. We need
to reverse the list by changing the links between nodes.
1. Initialize three nodes R as NULL, P as start and Q as NULL.
2. Iterate through the Linked List.
ALGORITHM ListReverse(START)
BEGIN:
IF START= NULL THEN
WRITE (“List is empty”)
ELSE
P = START, R = NULL
WHILE P! = NULL DO
Q = P→ Next
P→ Next = R
R=P
P=Q
START = R
END;
SEARCHING IN LINKED LIST
Above function performs the Linear Search on the Linked List. We can also perform the Binary
Search on the Linked List. For this we require the address of the Middle element in the linked
list. Subsequent methods are written to find the Middle element in the linked list.
Finding Middle Element in the Linked List
ALGORITHM FindMiddle(START)
BEGIN:
Q = START
P = START→next
WHILE P! = NULL || P→next != NULL || P→next→next!=NULL DO
Q = Q→next
P = P→next→next
RETRUN Q
END;
Binary Search on Linked List
ALGORITHM BinarySearch(START, item)
BEGIN:
IF START!=NULL THEN
Mid=FindMiddle(START)
IF Mid →info == item THEN
RETURN Mid
ELSE
IF item < Mid →info THEN
Mid →Next = NULL
BinarySearch(START, item)
ELSE
START=Mid →Next
BinarySearch(START, item)
ELSE
RETURN NULL
END;
LOOP DETECTION
Problem: Write an Algorithm
• To check if the link list has a loop or not.
• If link list has a loop then find a length of loop.
• Find start point of loop.
It is already understood that if there is loop or cycle in the link list then there is no end. It
means in this case normal traversal does not work because there is no idea where to stop.
LOGIC-
• First initialize visited field of all nodes is FALSE.
• After that traverse every node and set visited field of node is true.
• If again comes true then it means loop exist otherwise not.
ALGORITHM LoopFind(START)
BEGIN:
P = START
WHILE P! =NULL AND P→Next! =NULL AND P→visited==FALSE DO
P→visited=TRUE
P=P→Next
IF P→visited==TRUE THEN
WRITE (loop found)
ELSE
WRITE (loop not found)
END;
Here we traverse the one time the entire link list so complexity of link list is O(N) but initialize
visited field of all nodes so it takes O(N) extra space if variable consider otherwise O(1).
ALGORITHM LoopFind(START)
BEGIN:
P = START
Reverse(P)
IF P==START THEN
WRITE (“loop found”)
ELSE
WRITE (“loop not found”)
END;
This algorithm again takes O (N) time and constant space because just traverse the list single
time.
Method-3-
LOGIC-
• Here take two pointers slow and fast pointers and both pointers point to START node.
• Move slow pointer to normal speed but fast pointer to double speed.
• If fast pointers reach to NULL then it means there is no cycle because fast pointers move
to double speed and that time slow pointer points middle of the list.
• If slow and fast pointers are equal then there is a loop.
RETURN FALSE
END;
Complexity- here is the complexity is O(N) because traverse the list only once by slow pointer.
Time Complexity O(N)
Space Complexity O(1)
Length of Loop
First method-
If loop exists then the address containing in P and Q are same. Now move P two steps, Q one
step and increment count. Repeat this step till P does not become equal to Q and return count.
Second Method- Check until Q → Next not equal to P and increment count.
ALGORITHM LoopLength(START)
BEGIN:
P = START
Q = START
Count = 0
WHILE P != NULL and P→Next != NULL DO
Q = Q→ Next
P = P→ Next → Next
IF P==Q THEN
BREAK
SECOND METHOD
ALGORITHM LoopLength(START)
BEGIN:
P = START
Q = START
Count = 0
WHILE P != NULL and P → Next != NULL DO
Q = Q → Next
P = P → Next → Next
IF P==Q THEN
BREAK
Q=Q->Next
Count++
WHILE Q!=P//second method
Q = Q → Next
Count = Count + 1
RETURN Count
END;
P = START
WHILE P != Q DO
Q = Q → Next
P = P → Next
RETURN P
END;
Palindrome
Write an algorithm to check if a link list is palindrome or not.
Following list are palindrome
1→2→3→3→3→2→1
M → A→L→A→Y→A→L→A→M
Constraints – Function should take O(N)Time
Solution
The simplest solution is that to take reverse function.
Solution
1. first find middle of link list
2. then compare first half and second half of link list.
3. finally, again reverse the second half of list to store original one.
4. Total complexity O(N)
ALGORITHM Palindrome(START)
BEGIN:
P = START
Ispalindrome = TRUE
mid = middle(P)
Q=mid
reverse(mid)
//if number of elements is odd then let first half have the extra element
//check if corresponding elements of the list pointed by START and mid are equal
WHILE mid != NULL DO
IF mid→info != P→info THEN
Ispalindrome= FALSE
P =P → Next
mid=mid → Next
reverse(Q)
END;
Complexity- this algorithm takes O(N) time complexity because
1. first find middle of link list in O(N/2) time
2. then compare first half and second half of link list O(N/2)
3. finally, again reverse the list to store original one O(N/2),
Total complexity O(N)
Circular Linked List is more like Linear Linked List except that the address field of the last node
contains the address of the first node. START keeps the address of the last node in the circular
Linked List.
No of Link adjustments: 2
Insertion after the given Node
ALGORITHM InsAfter(Q, item)
BEGIN:
IF Q==NULL THEN
WRITE(“Void Insertion”)
ELSE
P = GetNode()
P→info = Item
P→Next=Q→Next
Q→Next=P
END;
Deletion at End
ALGORITHM DelEnd(cSTART)
BEGIN:
IF cSTART==NULL THEN
WRITE(“Void Deletion”)
ELSE
P=cSTART→Next
WHILE P→Next!=cSTART DO
P=P→Next
P→Next=cSTART→Next
Q=cSTART
IF cSTART→Next!=cSTART
cSTART=P
ELSE
cSTART=NULL
item=Q→Info
FreeNode(Q)
RETURN item
END;
Primitive operations
Insertion
Insertion at the Beginning
ALGORITHM InsBeg(dSTART,item)
BEGIN:
P=GetNode()
P→info=item
P→Prev=NULL
P→Next=dSTART
IF dSTART!=NULL
dSTART→Prev=P
dSTART=P
END;
Deletion
ALGORITHM DelBeg(dSTART)
BEGIN:
IF dSTART == NULL THEN
WRITE(“Void Deletion”)
ELSE
P=dSTART
Q=dSTART→Next
IF Q!=NULL THEN
Q→Prev=NULL
dSTART=Q
item=dSTART→Info
FreeNode(P)
RETURN item
END;
Time Complexity: O(1)
Here, in any case 7 statements are executed, which is a constant
Space Complexity: O(1)
Two extra variable P, Q are used. Total extra space allocated is constant
No of Link adjustments: 2
Traversal
ALGORITHM Traverse(dSTART)
BEGIN:
P=dSTART
WHILE P!=NULL DO
WRITE (P→Info)
P=P→Next
END;
Time Complexity: O(N)
Traversal requires O(N) Time and 1 other statement. Total time required asymptotically is O(N)
Space Complexity: O(1)
Two extra variable P is used. Total extra space allocated is constant
No of Link adjustments: 0
Circular Doubly Linked List
9.13.1 Introduction
Circular Doubly Linked List is the collection of nodes where each node has at least three field
• Next Address field- It contains the address of next node in the list.
• Previous Address field- It contains the address of previous node in the list.
• Information Field- It contains the actual data to be stored.
In this list Next address field of the last node contains the address of the first node
and previous address field of the last node contains the address of last node. No
node contains NULL. Also START variable contains the address of the first node in the list.
ALGORITHM InsBeg(cdSTART,item)
BEGIN:
P=GetNode()
P→info=item
IF cdSTART == NULL THEN
P→Prev = P
P→Next = P
ELSE
Q = cdSTART →Next
P→Next = Q
Q→Prev = P
P→Prev = cdSTART
cdSTART→Prev = P
END;
IF cdSTART==NULL THEN
P→Next = P
P →Prev = P
cdSTART = P
ELSE
Q = cdSTART →Next
cdSTART→Next = P
P→Prev = cdSTART
P → Next = Q
Q→ Prev = P
cdSTART = P
END;
This algorithm inserts an item at some position in the circular doubly Linked List. There is one
scenario of inserting a node in circular doubly Linked List at given position. If we need to insert a
node after some specific position (consisting one or more nodes) in the list than firstly, we find
the location of that node after which we can perform insertion.
ALGORITHM DelBeg(cdSTART)
BEGIN:
IF cdSTART == NULL THEN
WRITE(“Void Deletion”)
ELSE
P=cdSTART
IF P→Next != cdSTART THEN
P→Next→Prev = P→Prev
P→Prev→Next = P→Next
cdSTART = P→Next
ELSE
cdSTART = NULL
item=cdSTART→Info
FreeNode(P)
RETURN item
END;
Case 1:
Case 2:
Time Complexity: O(1)
Here, in any case 7 statements are executed, which is a constant
Space Complexity: O(1)
One extra variable P is used. Total extra space allocated is constant
No of Link adjustments: 2
ALGORITHM DelEnd(cdSTART)
BEGIN:
IF cdSTART==NULL THEN
WRITE(“Void Deletion”)
P=cdSTART
IF P→Next! = cdSTART THEN
cdSTART→Prev = P→Prev
P→Prev→Next = cdSTART
ELSE
cdSTART=NULL
Item=P→Info
FreeNode(P)
Return item
END;
Case 1:
Case 2:
ALGORITHM DelAfter(Q)
BEGIN:
IF P == NULL OR P→Next == P THEN
WRITE(“Void Deletion”)
ELSE
P = Q→Next
Q→Next = P→Next
P→Next→Prev = Q
IF P == cdSTART THEN
cdSTART = Q→Next
item=P→Info
FreeNode(P)
RETURN item
END;
Case 1:
Case 2:
Time Complexity: ϴ(1)
It takes only two statements when the Circular Linked List is empty and maximum 5 otherwise.
In both of the above cases, the number of statement execution is fixed i.e. constant
Space Complexity: ϴ(1)
Two extra variables P & item are utilized, which is a constant number.
No of Link adjustments: 2 or 3
Stack
Stacks are the ordered collection of items into which items may be inserted or removed from the
same end called TOP of the stack. Stack works on the principal of LIFO – last in first out scheme.
To ensure the LIFO behavior we can think of insertion and deletion of items from beginning of
the Linked List.
ALGORITHM Initialization (TOP)
BEGIN:
TOP = NULL
END;
ALGORITHM POP(TOP)
BEGIN:
IF TOP = = NULL THEN
WRITE (“Stack Underflows”)
RETURN
x = Delbeg(TOP)
RETURN x
END;
ALGORITHM Display(TOP)
BEGIN:
RETURN TOP → info
END;
Explanation: The above algorithm performs STACK implementation using Linked List. For each
STACK insertion, deletion and display operation PUSH ( ), POP( ), Display( ) functions are created
respectively.
Complexity:
Time Complexity: PUSH operation: O(1)
POP operation: O(1)
Display operation: O(1)
Space Complexity: PUSH operation: O(1)
POP operation: O(1)
Display operation: O(1)
Queue
Queues are the ordered collection of items into which items may be inserted at one end called
REAR of the queue and removed from another end called FRONT of the Queue. Queue works on
the principal of FIFO – First in first out scheme. To ensure the FIFO behavior we can think of
insertion at the end and deletion of items from beginning of the Linked List.
Explanation: The above algorithm performs QUEUE implementation using Linked List. For each
QUEUE Initialization, Insertion and deletion operation Initialize(), Enqueue( ), Dequeue ( )
functions are created respectively.
Complexity:
Time Complexity: Enqueue operation: O(1)
Dequeue operation: O(1)
Space Complexity: Enqueue operation: O(1)
Dequeue operation: O(1)
Priority Queue
Ascending PQ: Lower numbers are considered higher priority e.g. 1 means highest priority. Upon
subsequent deletions, the ascending sequence of priority numbers will appear.
Descending PQ: Higher numbers are considered higher priority. Upon subsequent deletions, the
descending sequence of priority numbers will appear.
Priority Queue can be implemented using Array, Linked List and Heaps.
For priority queue implementation using link list, add extra field priority is used in the node (along
with 2 usual fields as Info and Next).
For insertion of an item in the Priority Queue, following steps can be performed.
• If start contains NULL then it means simply insert the item as a first node.
• If start does not contain NULL then first compare priority field and insert according to
the priority.
• In case of deletion just free the first node as highest priority.
ALGORITHM DeQueue(START)
BEGIN:
IF START==NULL THEN
WRITE(“Void Deletion”)
RETURN
ELSE
Item=DelBeg(START)
RETURN Item
END;
Complexity-
EnQueue Algorithm takes O(N) time because traversal is required in the list and comparison of
the priority in just single pass.
DeQueue Algorithm requires O(1) time.
Both the Algorithms require O(1) Space.
Insertions
Insertion at Front
Insertion at Rear
ALGORITHM InsRear(DQ, item)
BEGIN:
IF DQ.REAR == NULL THEN
InsBeg(DQ.Rear, item)
DQ.FRONT = DQ.Rear
ELSE
InsAft(DQ.REAR, item)
END;
Deletions
Deletion at Front
ALGORITHM DelFront(DQ)
BEGIN:
IF EMPTY (DQ) THEN
WRITE (“Queue Underflows”)
EXIT (1)
ELSE
Item = DelBeg(DQ.FRONT)
IF DQ.FRONT == NULL THEN
DQ.REAR = NULL
RETURN item
END;
Deletion at Rear
ALGORITHM DelRear(DQ)
BEGIN:
IF EMPTY (DQ) THEN
WRITE (“Queue Underflows”)
EXIT (1)
ELSE
DQ.Rear = DQ.REAR → Left
IF DQ.Rear == NULL
Item = DelBeg(DQ.FRONT)
ELSE
Item = DelAft(DQ.REAR)
RETURN item
END;
A header node is a special node that is found at the beginning of the list. A list that contains
this type of node, is called the header-Linked List. This type of list is useful when information
other than that found in each node is needed. For example, suppose there is an application in
which the number of items in a list is often calculated. Usually, a list is always traversed to find
the length of the list. However, if the current length is maintained in an additional header node
that information can be easily obtained.
Similarly, header node can contain maximum or minimum information among all the nodes.
Sometimes header node denotes just the beginning of the Linked List and it contains invalid
information. E.g.
Generalized Linked List
A Generalized Linked List L, is defined as a finite sequence of n>=0 elements, l1, l2, l3, l4, …, ln,
such that li are either atom or the list of atoms. Thus
L = (l1, l2, l3, l4, …, ln)
where n is total number of nodes in the list.
To represent a list of items there are certain assumptions about the node structure.
• Flag = 1 implies that down pointer exists
• Flag = 0 implies that next pointer exists
• Data means the atom
• Down pointer is the address of node which is down of the current node
• Next pointer is the address of node which is attached as the next node
Example:
9x5 + 7xy4 + 10xz
In the above example the head node is of variable x. The temp node shows the first field as 2
means coefficient and exponent are present.
Since temp node is attached to head node and head node is having variable x, temp node
having coefficient = 9 and exponent = 5. The above two nodes can be read as 9x5. ↑
Similarly, in the above figure, the node temp1 can be read as x4.
The flag field is 1 means down pointer is there
temp2 = y
temp3 = coefficient = 7
exponent = 1
flag = 2 means the node contains coefficient and exponent values.
temp2 is attached to temp3 this means 7y1 and temp2 is also attached to temp1 means
temp1 x temp2
x4 x 7y1 = 7x4y1 value is represented by above figure
In case the Linked List were implemented using Array, a pool of nodes are created. Each GetNode
function allocates the node from this pool and nodes are collected back to this pool
corresponding to Freenode function. The nodes which are freed can be re-used by subsequent
calls to Getnode function.
• The Linked List consume more memory per data item as compared to Arrays as one
address field (minimum) is required for storing the address of the next node.
• Random access to the nodes is not possible, each time the traversal has to start from the
beginning of the Linked List (Sequential access)
• Back traversal in Linked List either requires the additional address field (as in the doubly
Linked List) or Recursion. Both increases the time space complexity further as compared
to array.