Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

3.1 Single Linked Lists

Download as pdf or txt
Download as pdf or txt
You are on page 1of 14

Linked Lists

• Linked List can be defined as collection of objects called nodes that are randomly stored in
the memory.
• A node contains two fields i.e. data stored at that particular address and the pointer which
contains the address of the next node in the memory.
• The last node of the list contains pointer to the null.

Uses of Linked List


• The list is not required to be contiguously present in the memory. The node can reside
anywhere in the memory and linked together to make a list. This achieves optimized
utilization of space.
• List size is limited to the memory size and doesn't need to be declared in advance.
• Empty node cannot be present in the linked list.
• We can store values of primitive types or objects in the singly linked list.

Why use linked list over array?


Till now, we were using array data structure to organize the group of elements that are to be
stored individually in the memory. However, Array has several advantages and disadvantages
which must be known in order to decide the data structure which will be used throughout the
program.
Array contains following limitations:
1. The size of array must be known in advance before using it in the program.
2. Increasing size of the array is a time taking process. It is almost impossible to expand the
size of the array at run time.
3. All the elements in the array need to be contiguously stored in the memory. Inserting any
element in the array needs shifting of all its predecessors.

Linked list is the data structure which can overcome all the limitations of an array. Using linked
list is useful because,
1. It allocates the memory dynamically. All the nodes of linked list are non-contiguously
stored in the memory and linked together with the help of pointers.
2. Sizing is no longer a problem since we do not need to define its size at the time of
declaration. List grows as per the program's demand and limited to the available memory
space.

Each node divided into two parts: the first part contains data field and the 2nd part called the
‘Link’ filed contains the address of the next node in the list. Such an address, which is used to
access a particular node, is known as a pointer. The entire linked list is accessed from an
Data Structure with Python, Dr. K. Bhowal
external pointer that points to (contains the address of) the first node in the list. (By an
“external” pointer, we mean one that is not included within the node. Rather its value can be
accessed directly by referencing a variable). Internal pointer on the other hand is a pointer
within the node. ‘next’ is the internal pointer in the next example.

Advantage of Linked lists:


Linked lists have many advantages. Some of the very important advantages are:
1. Linked lists are dynamic data structures. That is, they can grow during the execution of a
program.
2. Efficient memory utilization. Here, memory is not pre-allocated. Memory is allocated
whenever it is required. And it is de-allocated when it is no longer needed. (In case of
Array, a good amount of space is wasted)
3. Insertion and deletions are easier and efficient, linked lists provide flexibility in inserting a
data item at a specified position and deletion of a data item from the given position. (In
case of Array, right or left shifting is necessary for insertion and deletion of an element,
which increase the time complexity)
4. Many complex applications can be easily carried out with linked lists.

Disadvantage of Linked lists:


1. Extra memory is needed to store the address of the next or previous nodes. It is directly
proportional to the number of nodes in a list.
2. Access to an arbitrary data item is little bit cumbersome and also time consuming.

Representation of Linear Linked List:


Suppose we want to store list of values, then a node can be representing in memory with the following
class definition:
class Node:
def __init__(self):
self.data = None
self.next = None

The above declaration defines a new data type, who’s each element is of type Node type.
data next

Operations Linked List:


1. Creation of a Linked list
2. Display elements of a list
3. Insertion of a new node in the exiting linked list
4. Deletion of a new node
5. Searching an element in the linked list
6. Merging or concatenate of two linked lists
7. Splitting a linked list into two linked lists
8. Reverse a linked list

Data Structure with Python, Dr. K. Bhowal


Application of Linked List:
1. Polynomial Addition
2. Polynomial Multiplication

1. Creation of Linked list


Algorithm:
In this algorithm a Linked List of nodes is created. The list is pointed by pointer “Head”, the last node of
the list points to NULL., indicating the end of the list.
Each node is having two parts DATA and NEXT. Let us assume that a linked list of N number of nodes is
to be created. The operator new will be used for the dynamic allocation of node. A variable I is being used
as a counter to count the number of nodes in the created list.
1. Head = new node; {create the 1st node of the list pointed by first};
2. Read (Data (Head));
3. NEXT(Head) = NULL;
4. list = Head; [point list to the Head]
5. For I=1 to N-1 repeat steps 6 to 10
6. X = new node;
7. Read ( Data (X))
8. NEXT(X) = NULL;
9. NEXT(list) = X; {connect the nodes}
10. list = X; [shift the pointer to the last node of the list]
[end of For Loop]
11. END

Python implementation:
The following function creates a linked list where each node contains a value:
def createSLL(l):
while True:
x = int(input("Enter data:"))
l.data = x
ans = input("Do you want to create another node (y/n)?")
if ans == "n" or ans == "N":
break
else:
l.next = Node()
l = l.next

2. Display elements of a list


Algorithm:
1. If First=NULL then {print “List empty” STOP};
2. ptr=First; {point ptr to the 1st node}

Data Structure with Python, Dr. K. Bhowal


3.While ptr<> NULL repeat Steps 4 to 5
4. print(DATA(ptr));
5. ptr=NEXT(ptr) [shift ptr to the next node]
6. END
Python implementation:
def printList(slist):
while slist.next:
print(slist.data, end = " ")
slist = slist.next
print(slist.data, end = " ")

3. Insertion of a new node in the existing linked list


To insert an element into the following three things should be done:
1. Allocating a new node.
2. Assigning the data for new node.
3. Adjusting the pointers.

a) Before the First Node


1. If the list is empty then create a new node.
2. If the list is not empty, allocate memory for the new1 node and assign the value to the
data field of the new1node.
3. Then set the new1->next field to point to the head node.
4. Make the new1 node as a head node as head=new1;
Algorithm: Insert a new node at the beginning of a linked list.
In this algorithm a node X is inserted at the beginning of a linked list. The Linked List is being
pointed by a pointer First at the beginning.
1. X=new node;
2. Read (DATA(X));
3. If (FIRST=NULL) then {
First=X;
NEXT(X)=NULL;
}
else
{
NEXT(X)=First;
First=X;
}
4. END

Data Structure with Python, Dr. K. Bhowal


Python Implementation: Insert a new node at the beginning of a linked list.

def insertBegin(l):
newNode = Node()
x = int(input("Enter data for new node:"))
newNode.data = x
newNode.next = l
return newNode

b) After Last node: (Algorithm)


1. If the list is empty then create a new node.
2. If the list is not empty, allocate memory for the new node and assign the value to the data
field of the new node.
3. Then go to the last node (say, currently last node is list) and then set the list->next field to
point to the new node.
4. Make the linked field of the new node to point to NULL;

def insertAfterLastNode(l):
n1 = l
while n1.next:
n1 = n1.next

newNode = Node()
x = int(input("Enter data for new node:"))
newNode.data = x
newNode.next = n1.next
n1.next = newNode
return l

c) After a Specified Node:


Suppose we want to insert a new node after list node:
1. Allocate memory for the new node.
2. Assign value to the data field of the new node.
3. Go to the list node and then make the linked field of the new node to point to
list->next node.
4. Make the linked field of the list node to point to the new node.

Algorithm: Insert a new node after a specific Node


Let List be a pointer to a linked list. In this algorithm a node X is inserted in the list after a node
with data part equal to ‘VAL’. A pointer ptr travels the list in such a way that each visited node
is checked for data part equal to ‘VAL’. If such a node is found then node X is inserted after the
same.
1. Ptr=List;
2. While (ptr<>NULL) repeat steps 3 to 4
3. If (DATA(ptr)=’VAL’) then {
X=new node
Read (DATA(X));
Data Structure with Python, Dr. K. Bhowal
NEXT(X)=NEXT(ptr)
NEXT(ptr)=X;
BREAK;
}
4. ptr=NEXT(ptr)
[end of while]
5. END.
It may be noted in the above algorithm that in step 3 a function exit() has been used. The purpose
of this function is to leave the while loop.

Python Implementation: Insert a new node after a specific Node

def findNode(l, x):


while l.next:
if l.data == x:
return l
l = l.next
return None

def insertAfterSpecificNode(l):
d = int(input("Enter data of a node after which want to insert:"))
n1 = findNode(l,d)
if n1 == None:
print("Node not found")
return l

newNode = Node()
x = int(input("Enter data for new node:"))
newNode.data = x
newNode.next = n1.next
n1.next = newNode

return l

Insertion of a new node before any node:


a) Before head: (Algorithm)
1. Allocate memory for the new node.
2. Assign the value to the data field of the new node.
3. Make the linked field of the new node to point to the starting node of
the liked list.
4. Then, set the external pointer (which was pointing to the starting node)
to point to the new node.
b) Before the last node:
c) Before a specified node:
Algorithm: Insertion of a new node before any node
Let LIST be a pointer to a linked list. In this algorithm a node X is inserted in the list before a
node with data part equal to ‘VAL’ Two pointers ptr and back travel the list in such a way that
each visited node is checked for data part equal to ‘VAL’. If such a node is found then ptr points

Data Structure with Python, Dr. K. Bhowal


to the selected node and back point to immediate previous node in the list. The node X is inserted
before the selected node.
1. ptr=LIST
2. If(data(ptr)=’VAL’) then { [check if the first node is the desired one]
X=new node;
Read DATA(X);
NEXT(X)=LIST;
LIST=X;
STOP;
}
3. While(ptr<>NULL ) repeat step 4 to 6
4. back=ptr;
5. ptr=NEXT(ptr);
6. If(DATA(ptr)=’VAL’)then {
X=new node;
Read DATA(X);
NEXT(X)=ptr;
NEXT(back)=X;
EXIT;
}
[end of while loop]
7. END

4. Deletion of a node
Deletion of a node from linked list has the following three instances:
a) Deletion of head
b) Deletion of the last node
c) Deletion of a specified node.

In order to delete a node from the list, it is necessary to search for location of deletion. The steps
involved in deleting the node from the linked list are as follows:
1. If the linked list is empty then display the message “Deletion is not possible”.
2. If the node to be deleted is the first node (pointed to by head pointer) then set the pointer
head to point to the second node in the listed list.
3. If the node to be deleted is the last node, then go on locating the last but one node and set
its link field to point to UNLL pointer.
4. If the situation is other than the above three, then delete the node from specified position
within the linked list.

a) Deletion of head (Algorithm) :


1. If the list is not empty, then check whether the element below to the first node of the list.
2. Move the head pointer to the head->next node (head=head>next).
3. Free the first node.

b) Deletion of the node (Algorithm) :


Data Structure with Python, Dr. K. Bhowal
Exercise
c) Deletion of a specified node (Algorithm) :
Exercise

Program :
#Single Linked list creation & deletion operations
class Node:
def __init__(self):
self.data = None
self.next = None

def createSLL(l):
while True:
x = int(input("Enter data:"))
l.data = x
ans = input("Do you want to create another node (y/n)?")
if ans == "n" or ans == "N":
break
else:
l.next = Node()
l = l.next

def deleteFirstNode(h):
tempNode = h
h = h.next
tempNode.next = None
del tempNode
return h

def findNode(l, x):


while l.next:
if l.next.data == x:
return l
l = l.next
return None

def deleteSpecificNode(h):
d = int(input("Enter data of a node to delete:"))
l = findNode(h,d)

Data Structure with Python, Dr. K. Bhowal


if l == None:
print("Node not found")
return h

tempNode = l.next
l.next = l.next.next
tempNode.next = None
del tempNode
return h

def deleteLastNode(h):
l = h
while l.next.next:
l = l.next

tempNode = l.next
l.next = None
del tempNode
return h

def printList(slist):
while slist.next:
print(slist.data, end = " ")
slist = slist.next
print(slist.data, end = " ")

head = Node()
while True:
print("1. Create Linked List")
print("2. Display")
print("3. Delete First Node")
print("4. Delete a specific Node")
print("5. Delete last Node")
print("6. Exit")
x = int(input("Enter your choice:"))
if x == 1:
createSLL(head)
elif x == 2:
Data Structure with Python, Dr. K. Bhowal
printList(head)
elif x == 3:
head = deleteFirstNode(head)
elif x == 4:
head = deleteSpecificNode(head)
elif x == 5:
head = deleteLastNode(head)
elif x == 6:
break
else:
print("Wrong choice")

5. Searching an element in the linked list:


Algorithm: Search
In this algorithm a linked list, pointed by first, is traversed. While traversing the data part of each
visited node is compared with an item ‘x’. If the item is found then the search stops otherwise the
process continues til the end of the list(i.e NULL) is encountered. A pointer ptr is being used to
visit the various nodes in the list.
1. If first=None then{
Print “List empty”;
STOP;
}
2. ptr=First; [point ptr to the 1st node]
3. while (ptr<> None) repeat steps 4 to 5
4. If (DATA (ptr)= ‘X’) Then {
print “item found”;
STOP
}
5. ptr=NEXT (ptr); [shift ptr to the next node]
[end of while]
6. Print “item not found”;
7. END
It may be noted in the above algorithm that if the item ‘X’ is found then the search stops.

6. Merging or concatenate of two linked lists:


Suppose we have two linked lists with starting nodes named list1, list2 respectively. We have to
merge these two linked lists to single linked list.

def merge()
{
list1= Node()
list2=Node()
Data Structure with Python, Dr. K. Bhowal
print(“Enter data for List:”)
createSLL(list)
print(“Enter data for list2:”)
createSLL(list2)
11=list
While 11.next!=None:
11=11.next
11.next=list2
print(list)
}

7. Splitting a linked list into two inked lists:

def spilt(list)
{
key = int(input(“Enter key for 2nd head:”))
head1=list
while list.next.data!=key:
list=list.next

head2=list.next
list.next=None

print(head2)
print(head2)
}

8. Reverse a linked list:


def reverse(h)
{
p = None
c = h
while h != None:
h=h.next;
c . next = p;
p = c;
c = h;

return p;
}

Polynomial Addition:
Linked lists are widely used to represent and manipulate polynomials, polynomials are the
expression containing number of terms with nonzero coefficients and exponents. In the linked
list representation of polynomials, each term is considered as node. And such a node contains
three fields:
1. Coefficient field-> holds the value of the coefficient of a term.
2. Exponent field-> holds the exponent value to that term.
3. Linked field-> holds the address of the next term of the polynomial.
Data Structure with Python, Dr. K. Bhowal
The logical representation of the above node is given below:
class Node:
def __init__(self):
self.coef = None
self.exp = None
self.next = None

The steps involved in adding two polynomials are given below:


1. Read the coefficient and exponents of the first polynomial.
2. Read the coefficient and exponents of the second polynomial.
3. Set the temporary pointers p and q to traverse the two polynomials respectively.
4. Compare the exponents of two polynomials starting from the first nodes.
• If both exponents are equal then add the coefficients and store it in the resultant linked list.
• If the exponent of the current term in the first polynomial p is less than the exponent of the
current term of the second polynomial is added to the resultant linked list. And move the
pointer q to point to the next node in the second polynomial q.
• If the exponent of the current term in the first polynomial p is greater than the exponent of
the current term in the second polynomial q, then the current term of the first polynomial is
added to the resultant linked list. And move the pointer p to the next node.
• Append the remaining nodes of either of the polynomials to the resultant linked list.

#Polynomial addition
class Node:
def __init__(self):
self.coef = None
self.exp = None
self.next = None

def createPoly(p):
while True:
coef = int(input("Enter coeficient:"))
exp = int(input("Enter power:"))
p.coef = coef
p.exp = exp
ans = input("Another term (y/n)?")
if ans == "n" or ans == "N":
break
else:
p.next = Node()
p = p.next

def displayPoly(p):
while p != None:
print(p.coef, "x^",p.exp , end = " ")
p = p.next
Data Structure with Python, Dr. K. Bhowal
def addPoly(poly1,poly2):
poly3 = Node()
p1 = poly1
p2 = poly2
p3 = poly3

if p1 == None:
return p2
if p2 == None:
return p1

while p1 != None and p2 != None:


if p1.exp == p2.exp:
p3.coef = p1.coef + p2.coef
p3.exp = p1.exp
p1 = p1.next
p2 = p2.next
elif p1.exp > p2.exp:
p3.coef = p1.coef
p3.exp = p1.exp
p1 = p1.next
else:
p3.coef = p2.coef
p3.exp = p2.exp
p2 = p2.next

p3.next = Node()
p3 = p3.next

if p1 != None:
while p1 != None:
p3.coef = p1.coef
p3.exp = p1.exp
p1 = p1.next
p3.next = Node()
p3 = p3.next
if p2 != None:
while p2 != None:
p3.coef = p2.coef
p3.exp = p2.exp
p2 = p2.next
p3.next = Node()
p3 = p3.next

return poly3

p1 = Node()
Data Structure with Python, Dr. K. Bhowal
p2 = Node()
print("Enter Polynomial 1:")
createPoly(p1)
print("Polynomial 1:")
displayPoly(p1)

print()
print("Enter Polynomial 2:")
createPoly(p2)
print("Polynomial 2:")
displayPoly(p2)

print()
p3 = addPoly(p1,p2)
print("Polynomial 3:")
displayPoly(p3)

Advantage & Disadvantage of Single Linked Lists:

Advantages:
1. Accessibility of a node in the forward direction is easier.
2. Insertion and deletion of nodes are easier.

Disadvantages:
1. Accessing the preceding node of a current node is not possible as there is no backward
traversal.
2. Accessing a node is time-consuming.

Data Structure with Python, Dr. K. Bhowal

You might also like