Data Structures Module 3 QB Complete Solutions
Data Structures Module 3 QB Complete Solutions
PART A
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
self.last_node = None
def display(self):
current = self.head
while current:
print(current.data, end = ' ')
current = current.next
count = 0
while current:
if current.data == key:
count = count + 1
current = current.next
return count
a_llist = LinkedList()
for data in [5, 1, 3, 5, 5, 15, 4, 9, 2]:
a_llist.append(data)
print('The linked list: ', end = '')
a_llist.display()
print()
class LinkedList:
def __init__(self):
self.head = None
self.last_node = None
def display(self):
current = self.head
while current is not None:
print(current.data, end = ' ')
current = current.next
index = 0
while current:
if current.data == key:
return index
current = current.next
index = index + 1
return -1
a_llist = LinkedList()
for data in [4, -3, 1, 0, 9, 11]:
a_llist.append(data)
print('The linked list: ', end = '')
a_llist.display()
print()
class LinkedList(object):
def __init__(self):
self.head = None
# head of list
class Node(object):
def __init__(self, d):
self.data = d
self.next = None
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
self.last_node = None
def print_middle(llist):
current = llist.head
length = 0
while current:
current = current.next
length = length + 1
current = llist.head
for i in range((length - 1)//2):
current = current.next
if current:
if length % 2 == 0:
print('The two middle elements are {} and {}.'
.format(current.data, current.next.data))
else:
print('The middle element is
{}.'.format(current.data))
else:
print('The list is empty.')
a_llist = LinkedList()
print_middle(a_llist)
class Node:
# Constructor to create a new node
def __init__(self, data):
self.data = data
self.next = None
self.prev = None
class DoublyLinkedList:
# Constructor for empty Doubly Linked List
def __init__(self):
self.head = None
# 1. Allocates node
# 2. Put the data in it
new_node = Node(new_data)
# Driver code
dll = DoublyLinkedList()
dll.push(2)
dll.push(4)
dll.push(8)
dll.push(10)
class Node:
ptr1.next = self.head
else:
ptr1.next = ptr1 # For the first node
self.head = ptr1
if self.head is None:
return
head.push(12)
head.push(56)
head.push(2)
head.push(11)
Single and double linked lists are two types of linked lists. The main
difference between Single Linked List and Doubly Linked List is that a
node in the single linked list stores the address of the next node while a
node in a double linked list stores the address of the next node and the
previous node.
10) Write a program to modify the linked list such that all even
numbers appear before all the odd numbers in the modified linked list.
# Node class
class Node:
while(currNode != None):
val = currNode.data
global head
# 1 & 2: Allocate the Node &
# Put in the data
new_node = Node(new_data)
push(11)
push(10)
push(9)
push(6)
push(4)
push(1)
push(0)
segregateEvenOdd()
PART B
Since the question has only asked us to create and traverse, we will not
be using the insert function add nodes. You can also add an insert
function in the class and use them to push nodes into the list.
The code below can be used to add nodes without insertion function.
llist = LinkedList()
llist.head = Node(1)
second = Node(2)
third = Node(3)
llist.head.next = second; # Link first node with second
second.next = third; # Link second node with the third node
llist.printList()
OUTPUT
1 2 3
Front of list:
After a Node:
def insertAfter(self, prev_node, new_data):
End of list:
Iterative method
def getCount(self):
temp = self.head # Initialise temp
count = 0 # Initialise count
Recursive method
def getCountRec(self, node):
if (not node): # Base case
return 0
else:
return 1 + self.getCountRec(node.next)
class Node:
def __init__(self,data):
self.data = data;
self.next = None;
class DeleteMid:
#Represent the head and tail of the singly linked list
def __init__(self):
self.head = None;
self.tail = None;
self.size = 0;
#deleteFromMid() will delete a node from the middle of
the list
def deleteFromMid(self):
#Checks if list is empty
if(self.head == None):
print("List is empty");
return;
else:
#Store the mid position of the list
count = (self.size//2) if(self.size % 2 == 0)
else((self.size+1)//2);
#Checks whether head is equal to tail or not, if
yes then the list has only one node.
if( self.head != self.tail ):
#Initially, temp will point to head
temp = self.head;
current = None;
if(current != None):
#temp is the middle that needs to be removed.
#So, the current node will point to the node next to temp by
skipping temp.
current.next = temp.next;
#Delete temp
temp = None;
#If current points to None then, head and
tail will point to nodes next to temp.
else:
self.head = self.tail = temp.next;
#Delete temp
temp = None;
#If the list contains only one element
#then it will remove it and both head and tail
will point to None
else:
self.head = self.tail = None;
self.size = self.size - 1;
6) Write a program to reverse a singly linked list of length n?
Note: ADD DISPLAY OPERATION AND MAKE A LINKED LIST TO
COMPLETE THE PROGRAM
class Node:
# Constructor to initialize the node object
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
# Function to initialize head
def __init__(self):
self.head = None
# Function to reverse the linked list
def reverse(self):
prev = None
current = self.head
while(current is not None):
next = current.next
current.next = prev
prev = current
current = next
self.head = prev
# 1. Allocates node
# 2. Put the data in it
new_node = Node(new_data)
if (self.last != None):
return self.last
previous.next = current.next
head = previous.next
return head
9) Write a program to merge two sorted linked lists into a third linked
list using recursion?
class Node:
def __init__(self, data):
self.data = data
self.next = None
while temp :
print(temp.data, end="->")
temp = temp.next
if self.head is None:
self.head = new_node
return
last = self.head
while last.next:
last = last.next
last.next = new_node
else:
# If List2's data is greater than or equal List1's
# data assign temp to head2
temp = head2
# Driver Function
if __name__ == '__main__':
# Create linked list :
# 10->20->30->40->50
list1 = LinkedList()
list1.append(10)
list1.append(20)
list1.append(30)
list1.append(40)
list1.append(50)
class DoublyLinkedList:
# Constructor for empty Doubly Linked List
def __init__(self):
self.head = None
# Base Case
if self.head is None or dele is None:
return
Algorithm:
i) Let the node to be deleted be del.
ii) If the node to be deleted is the head node, then change the head
pointer to the next current head.
if headnode == del then
headnode = del.nextNode
iii)Set next of previous to del, if previous to del exists.
if del.nextNode != none
del.nextNode.previousNode = del.previousNode
iv)Set prev of next to del, if next to del exists.
if del.previousNode != none
del.previousNode.nextNode = del.next
Insertion at beginning:
Algorithm :
1. if head = None, then
new_node = node(data)
self.head = new_node
else:
create object of node
2. nb = Node(data)
3. nb.next = self.head
4. self.head = nb
Insertion at end:
Algorithm:
Basic Operation:
Following are basic operations of Queue:
EnQueue:
Inserting an element in Queue.
Pseudo Code:
Step 1 : Create a newNode with a given value and set 'newNode → next'
to NULL.
Step 2 : Check whether queue is Empty (rear == NULL)
Step 3 : If it is Empty then, set front = newNode and rear = newNode.
Step 4 : If it is Not Empty then, set rear → next = newNode and rear =
newNode.
DeQueue:
Deleting an element from Queue.
Pseudo Code:
Step 1 : Check whether the queue is Empty (front == NULL).
Step 2 : If it is Empty, then display "Queue is Empty!!! Deletion is not
possible!!!" and terminate from the function
Step 3 : If it is Not Empty then, define a Node pointer 'temp' and set it to
'front'.
Step 4 : Then set 'front = front → next' and delete 'temp' (free(temp)).
Display:
To display all elements present in Queue, we will take one temp(you can
give whatever name you want) pointer and make that to point front.
Then we traverse up-to rear or we can say temp!=NULL using
temp=temp->next (which will make our pointer move towards the rear)
and print temp->data.
Pseudo Code:
Step 1 : Check whether the queue is Empty (front == NULL).
Step 2 : If it is Empty then, display 'Queue is Empty!!!' and terminate the
function.
Step 3 : If it is Not Empty then, define a Node pointer 'temp' and initialize
with front.
Step 4 : Display 'temp → data -->' and move it to the next node. Repeat
the same until 'temp' reaches to 'rear' (temp → next != NULL).
Step 5 : Finally! Display 'temp → data --> NULL'.
Algorithm:
1)Create a new linked list, newHead to store the resultant list.
2)Traverse both lists until one of them is null.
3)If any list is null, insert the remaining node of another list in the
resultant list.
Otherwise compare the degree of both nodes, a (first list’s node) and
b (second list’s node). Here three cases are possible:
a) If the degree of a and b is equal, we insert a new node in the resultant
list with the coefficient equal to the sum of coefficients of a and b and
the same degree.
b) If the degree of a is greater than b, we insert a new node in the
resultant list with the coefficient and degree equal to that of a.
c) If the degree of b is greater than a, we insert a new node in the
resultant list with the coefficient and degree equal to that of b.
15) Explain how a linked list can be used for representing polynomials
using a suitable example.
Inserting element in the linked list involves reassigning the pointers from
the existing nodes to the newly inserted node. Depending on whether
the new data element is getting inserted at the beginning or at the
middle or at the end of the linked list, we have the below scenarios.
This involves pointing the next pointer of the new data node to the
current head of the linked list. So the current head of the linked list
becomes the second data element and the new node becomes the head
of the linked list.
Example:
class Node:
def __init__(self, dataval=None):
self.dataval = dataval
self.nextval = None
class SLinkedList:
def __init__(self):
self.headval = None
# Print the linked list
def listprint(self):
printval = self.headval
while printval is not None:
print (printval.dataval)
printval = printval.nextval
def AtBegining(self,newdata):
NewNode = Node(newdata)
list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")
list.headval.nextval = e2
e2.nextval = e3
list.AtBegining("Sun")
list.listprint()
Example:
class Node:
def __init__(self, dataval=None):
self.dataval = dataval
self.nextval = None
class SLinkedList:
def __init__(self):
self.headval = None
# Function to add newnode
def AtEnd(self, newdata):
NewNode = Node(newdata)
if self.headval is None:
self.headval = NewNode
return
laste = self.headval
while(laste.nextval):
laste = laste.nextval
laste.nextval=NewNode
# Print the linked list
def listprint(self):
printval = self.headval
while printval is not None:
print (printval.dataval)
printval = printval.nextval
list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")
list.headval.nextval = e2
e2.nextval = e3
list.AtEnd("Thu")
list.listprint()
Example:
class Node:
def __init__(self, dataval=None):
self.dataval = dataval
self.nextval = None
class SLinkedList:
def __init__(self):
self.headval = None
# Function to add node
def Inbetween(self,middle_node,newdata):
if middle_node is None:
print("The mentioned node is absent")
return
NewNode = Node(newdata)
NewNode.nextval = middle_node.nextval
middle_node.nextval = NewNode
list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Thu")
list.headval.nextval = e2
e2.nextval = e3
list.Inbetween(list.headval.nextval,"Fri")
list.listprint()
Deletion at beginning:
Deletion in singly linked list at the end. There are two scenarios in which
a node is deleted from the end of the linked list. There is only one node
in the list and that needs to be deleted. There are more than one node in
the list and the last node of the list will be deleted.
Example:
class Node:
def __init__(self, data):
self.data = data
self.next = None
#class LinkedList
class LinkedList:
def __init__(self):
self.head = None
Example:
class Node:
def __init__(self, data):
self.data = data
self.next = None
Example:
class Node:
def __init__(self, data):
self.data = data
self.next = None
#class LinkedList
class LinkedList:
def __init__(self):
self.head = None
Algorithm:
Let us suppose we have to delete node 'delete'
1) If the node to be deleted is the head node, then change the head
pointer to the next current head.
Example: if node with data '10' is to be deleted then head will point to
'20'
currNode = head
while currNode:
if currNode.data == userData:
currNode.prevNode.nextNode = currNode.nextNode
currNode.nextNode.prevNode = currNode.prevNode
del currNode
break
currNode = currNode.nextNode
class newNode:
def __init__(self, data):
self.data = data
self.left = self.right = None
# Base Case
if (root == None):
return None
else:
return None
# Driver Code
if __name__ == '__main__':
k = [45]
root = newNode(1)
root.left = newNode(2)
root.right = newNode(3)
root.left.left = newNode(4)
root.left.right = newNode(5)
root.right.left = newNode(6)
root.right.right = newNode(7)
root.left.left.left = newNode(8)
root.left.left.right = newNode(9)
root.left.right.left = newNode(12)
root.right.right.left = newNode(10)
root.right.right.left.right = newNode(11)
root.left.left.right.left = newNode(13)
root.left.left.right.right = newNode(14)
root.left.left.right.right.left = newNode(15)
PART C
Applications:
i) Implementation of stacks and queues
ii) Implementation of graphs : Adjacency list representation of graphs is
most popular which uses linked lists to store adjacent vertices.
iii) Dynamic memory allocation : We use a linked list of free blocks.
iv) Maintaining directory of names
v) Performing arithmetic operations on long integers
vi) Manipulation of polynomials by storing constants in the node of
linked list
vii) representing sparse matrices
3) Write the advantages of doubly linked lists over singly linked lists?
A singly circular list consists of only one additional pointer named 'Next'.
The 'Next' of each node, except the last node, will contain the address
of the upcoming node. The last node's 'Next' will store the address of
the first node.
8) Consider a single linked list, list out any two operations that can be
implemented in O(1) time?
1) can insert node and get the address of that node into head pointer
and next of that node contains next node address
2) As tail pointer is present new node address is stored in tail and even
in last but 1 node of linked list
3) Could be deleted easily but pointing head to the next node
All this could be done with O(1)
(or)
i) Insertion at the front of the linked list
ii) Insertion at the end of the linked list
iii) Deletion of the front node of the linked list
9 &10)
def fun1(head):
if(head == None):
return
fun1(head.next)
print(head.data, end = “ “)
fun1() prints the given Linked List in reverse manner. For Linked List
1->2->3->4->5, fun1() prints 5->4->3->2->1.
13) Identify the variant of linked list in which none of the node
contains a NULL pointer?
A list in which the last node points back to the header node is called a
circular linked list. The chains do not indicate first or last nodes. In this
case, external pointers provide a frame of reference because the last
node of a circular linked list does not contain the NULL pointer.
14) In a circular linked list, how many pointers require modification if a
node is inserted?
Two Pointers
15) Identify the searching technique for which linked lists are not
suitable data structures?
Binary search of the data structure link lists are not suitable.
(or)
Not Suitable for:
Binary search: Because finding mid element itself takes O(n) time.
16) In the worst case, find the number of comparisons needed to
search a singly linked list of length n for a given element?
Singly linked list has uni – directional flow, i.e., it has only one pointer for
moving (the next pointer).
In the worst case, for searching an element in the singly linked list, we
will have to traverse the whole list (the case when the required element
is either the last element or is not present in the list).
So, in the worst case for a list of length n, we will have to go to each
node for comparison and thus, we would be needing ‘n’ comparisons.
17) State the name of the data structure in which data elements are
logically adjacent to each other?
Linked allocation
Detailed Explanation:
In linked allocation, each file is a linked list of disk blocks. The directory
contains a pointer to the first and optionally the last block of the file.
With linked allocation, each directory entry has a pointer to the first disk
block of the file.
18) Write the disadvantages of doubly linked lists over singly linked
lists?