Stacks and Queue Using List and Linked List - New - Jupyter Notebook
Stacks and Queue Using List and Linked List - New - Jupyter Notebook
Linked list
Understanding Linked Lists
Linked lists are an ordered collection of objects. So what makes them different from normal
lists? Linked lists differ from lists in the way that they store elements in memory. While lists use
a contiguous memory block to store references to their data, linked lists store references as part
of their own elements.
Main Concepts
Before going more in depth on what linked lists are and how you can use them, you should first
learn how they are structured. Each element of a linked list is called a node, and every node has
two different fields:
Data contains the value to be stored in the node. Next contains a reference to the next node on
the list. Here’s what a typical node looks like:
A linked list is a collection of nodes. The first node is called the head, and it’s used as the
starting point for any iteration through the list. The last node must have its next reference
pointing to None to determine the end of the list. Here’s how it looks:
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 1 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
Memory is wasted because the Linked List requires extra memory to store.
It cannot access elements randomly.
It is very difficult to perform Reverse Traversing.
class SingleLinkedList:
def __init__(self):
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 2 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
def __init__(self):
self.head=None
def display_list(self):
if self.head is None:
print("Empty List")
else:
print("Elements in the list are: ")
p=self.head
while p is not None:
print(p.data,"-->",end='')
p=p.ref
print()
def count_nodes(self):
p=self.head
n=0
while p is not None:
n+=1
p=p.ref
print("Number of nodes in the list is= ",n )
def search(self,x):
p=self.head
position=1
while p is not None:
if p.data==x:
print("Found element =",x," At position = ",position)
return True
else:
p=p.ref
position+=1
print("Could not find element =",x)
return False
def insert_at_beginning(self,data):
temp=Node(data)
temp.ref=self.head
self.head=temp
def insert_at_end(self,data):
temp=Node(data)
# Case of empty list
if self.head is None:
self.head=temp
return
## Non-empty list, first traverse the list
p=self.head
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 3 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
p=self.head
while p.ref is not None:
p=p.ref
#Now p is pointing to last node in the list
p.ref=temp
## Create list:
def create_list(self):
data=int(input("Enter Element to be inserted: "))
temp=Node(data)
# Case of empty list
if self.head is None:
# temp=Node(data)
self.head=temp
return
## Non-empty list, first traverse the list
p=self.head
while p.ref is not None:
p=p.ref
#Now p is pointing to last node in the list
#temp=Node(data)
p.ref=temp
def insert_at_position(self,data,k):
if k==1:
temp=Node(data)
temp.ref=self.head
self.head=temp
return
## Need to find position before k
p=self.head
i=1
while i < k-1 and p is not None:
p=p.ref
i+=1
if p is None: ## outside list bounds
print("you cannot insert beyond position index ",i)
else:
temp=Node(data)
temp.ref=p.ref
p.ref=temp
def delete_node(self,del_element):
if self.head is None: #Case of Empty List
print("Empty List!")
return
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 4 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
return
# Case first node contain value "del_element"
if self.head.data==del_element:
self.head=self.head.ref
return
## Traverse list up until predecessor of node containing "del_element"
p=self.head
while p.ref is not None:
if p.ref.data==del_element: # Check if next cell contain "del_e
break
p=p.ref
if p.ref is None:
print("Element ",del_element, "is not in the list")
else:
p.ref=p.ref.ref
list=SingleLinkedList()
while True:
print("1. Create a List")
print("2. Insert at beginning of a list")
print("3. Insert an element at the end of a list")
print("4. Insert a node at a specified position")
print("5. Delete any node value")
print("6. Display list")
print("7. Count the number of nodes")
print("8. Search for an element")
print("9. Quit")
if option==6:
list.display_list()
elif option==1:
list.create_list()
elif option==7:
list.count_nodes()
elif option==8:
data=int(input("Enter the element you want to search for "))
list.search(data)
elif option==2:
data=int(input("Enter the element to be inserted"))
list.insert_at_beginning(data)
elif option==3:
data=int(input("Enter the element to be inserted"))
list.insert_at_end(data)
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 5 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
list.insert_at_end(data)
elif option==4:
data=int(input("Enter the element to be inserted"))
k=int(input("Enter the position at which to insert"))
list.insert_at_position(data,k)
elif option==5:
data=int(input("Enter element to be deleted "))
list.delete_node(data)
elif option==9:
break
else:
print("Choose the right Option")
print()
1. Create a List
2. Insert at beginning of a list
3. Insert an element at the end of a list
4. Insert a node at a specified position
5. Delete any node
6. Display list
7. Count the number of nodes
8. Search for an element
9. Quit
Enter your Choice: 1
Enter Element to be inserted: 22
1. Create a List
2. Insert at beginning of a list
3. Insert an element at the end of a list
4. Insert a node at a specified position
5. Delete any node
6. Display list
7. Count the number of nodes
8. Search for an element
9. Quit
Enter your Choice: 1
Enter Element to be inserted: 33
1. Create a List
2. Insert at beginning of a list
3. Insert an element at the end of a list
4. Insert a node at a specified position
5. Delete any node
6. Display list
7. Count the number of nodes
8. Search for an element
9. Quit
Enter your Choice: 1
Enter Element to be inserted: 44
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 6 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
1. Create a List
2. Insert at beginning of a list
3. Insert an element at the end of a list
4. Insert a node at a specified position
5. Delete any node
6. Display list
7. Count the number of nodes
8. Search for an element
9. Quit
Enter your Choice: 5
Enter element to be deleted 44
1. Create a List
2. Insert at beginning of a list
3. Insert an element at the end of a list
4. Insert a node at a specified position
5. Delete any node
6. Display list
7. Count the number of nodes
8. Search for an element
9. Quit
Enter your Choice: 6
Elements in the list are:
22 -->33 -->
1. Create a List
2. Insert at beginning of a list
3. Insert an element at the end of a list
4. Insert a node at a specified position
5. Delete any node
6. Display list
7. Count the number of nodes
8. Search for an element
9. Quit
Enter your Choice: 9
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 7 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
class Node:
def __init__(self,data):
self.data = data
self.nref = None
self.pref = None
class dLinkedList:
def __init__(self):
self.head = None
def display(self):
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 8 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
def display(self):
if self.head is None:
print("Linked list is empty!")
else:
p = self.head
while p is not None:
print(p.data,"-->",end=" ")
p = p.nref
def display_reverse(self):
print()
if self.head is None:
print("Linked list is empty!")
else:
p = self.head
while p.nref is not None:
p = p.nref
while p is not None:
print(p.data,"-->",end=" ")
p = p.pref
def creation(self,data):
if self.head is None:
new_node = Node(data)
self.head = new_node
else:
print("Linked List is not empty!")
def add_begin(self,data):
new_node = Node(data)
if self.head is None:
self.head = new_node
else:
new_node.nref = self.head
self.head.pref = new_node
self.head = new_node
def add_end(self,data):
new_node = Node(data)
if self.head is None:
self.head = new_node
else:
p=self.head
while p.nref is not None:
p=p.nref
p.nref = new_node
new_node.pref = p
def insert_at_position(self,data,k):
if k==1:
new_node=Node(data)
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 9 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
new_node=Node(data)
new_node.nref=self.head
self.head.pref=new_node
self.head=new_node
return
## Need to find position before k
p=self.head
i=1
while i < k-1 and p is not None:
p=p.nref
i+=1
if p.nref is None: ## outside list bounds
print("you cannot insert beyond position index ",i)
else:
new_node=Node(data)
new_node.nref=p.nref
p.nref.pref= new_node
p.nref=new_node
new_node.pref=p
def delete_node(self,del_element):
print()
if self.head is None:
print("The list has no element to delete")
return
if self.head.nref is None:
if self.head.data == del_element:
self.head = None
else:
print("element is not found in the list")
return
if self.head.data == del_element:
self.head = self.head.nref
self.head.pref = None
return
p = self.head
while p.nref is not None:
if p.data == del_element:
break;
p = p.nref
if p.nref is not None:
p.pref.nref = p.nref
p.nref.pref = p.pref
else:
if p.data == del_element:
p.pref.nref = None
else:
print("Element not found")
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 10 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
DLL = dLinkedList()
DLL.creation(10)
DLL.add_begin(20)
DLL.add_end(70)
DLL.add_end(80)
DLL.add_end(90)
DLL.insert_at_position(100,1)
DLL.display()
DLL.delete_node(90)
DLL.display()
DLL.display_reverse()
Circular linked list is a linked list where all nodes are connected to form a circle. There is no
NON at the end. A circular linked list can be a singly circular linked list or doubly circular linked
list.
Any node can be a starting point. We can traverse the whole list by starting from any point.
We just need to stop when the first visited node is visited again.
Circular lists are useful in applications to repeatedly go around the list. For example, when
multiple applications are running on a PC, it is common for the operating system to put the
running applications on a list and then to cycle through them, giving each of them a slice of
time to execute, and then making them wait while the CPU is given to another application.
It is convenient for the operating system to use a circular list so that when it reaches the
end of the list it can cycle around to the front of the list.
class CircularLinkedList:
ptr1.next = self.head
else:
ptr1.next = ptr1 # For the first node
self.head = ptr1
Stacks
Stack is an ordered collection of data elements into which new elements may be inserted
and from which elements may be deleted at one end called the “TOP” of stack.
A stack is a last-in-first-out ( LIFO ) structure.
Insertion operation is referred as “PUSH” and deletion operation is referred as “POP”.
The most accessible element in the stack is the element at the position “TOP”.
Stack must be created as empty.
Whenever an element is pushed into stack, it must be checked whether the stack is full or
not.
Whenever an element is popped form stack, it must be checked whether the stack is empty
or not.
We can implement the stack ADT either with array or linked list.
Applications of stack
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 13 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
1. Create a class Stack with instance variable items initialized to an empty list.
2. Define methods push, pop and is_empty inside the class Stack.
3. The method push appends data to items.
4. The method pop pops the first element in items.
5. The method is_empty returns True only if items is empty.
6. Create an instance of Stack and present a menu to the user to perform operations on the
stack.
In [ ]: class Stack:
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def pop(self):
return self.items.pop()
s = Stack()
while True:
print('1 push')
print('2 pop')
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 14 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
print('2 pop')
print('3 peek')
print('4 show')
print('5 quit')
operation = input('What would you like to do? ')
if operation == '1':
val = int(input('Enter the value '))
s.push(val)
elif operation == '2':
if s.is_empty():
print('Stack is empty.')
else:
print('Popped value: ', s.pop())
elif operation == '3':
print('peek value : ', s.peek())
elif operation == '4':
print('Stack values: ', s.show())
elif operation == '5':
break
1 push
2 pop
3 peek
4 show
5 quit
What would you like to do? 1
Enter the value 20
1 push
2 pop
3 peek
4 show
5 quit
What would you like to do? 1
Enter the value 30
1 push
2 pop
3 peek
4 show
5 quit
What would you like to do? 1
Enter the value 40
1 push
2 pop
3 peek
4 show
5 quit
What would you like to do? 1
Enter the value 70
1 push
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 15 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
1 push
2 pop
3 peek
4 show
5 quit
What would you like to do? 4
Stack values: [20, 30, 40, 70]
1 push
2 pop
3 peek
4 show
5 quit
What would you like to do? 2
Popped value: 70
1 push
2 pop
3 peek
4 show
5 quit
What would you like to do? 4
Stack values: [20, 30, 40]
1 push
2 pop
3 peek
4 show
5 quit
What would you like to do? 3
peek value : 40
1 push
2 pop
3 peek
4 show
5 quit
What would you like to do? 1
Enter the value 10
1 push
2 pop
3 peek
4 show
5 quit
What would you like to do? 4
Stack values: [20, 30, 40, 10]
1 push
2 pop
3 peek
4 show
5 quit
In [ ]: # Stack using Linked List
class Node:
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 16 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
self.data = data
self.next = None
class Stack:
def __init__(self):
self.head = None
def pop(self):
if self.head is None:
return None
else:
popped = self.head.data
self.head = self.head.next
return popped
def display(self):
if self.head is None:
print("Stack is empty")
else:
print("Elements in the list are: ")
p = self.head
while p is not None:
print(p.data)
p = p.next
print()
a_stack = Stack()
while True:
print('1.Push')
print('2.Pop')
print('3.Display')
print('4.Quit')
operation = input('What would you like to do? ')
if operation == '1':
data = int(input("Enter the iteam to be inserted:"))
a_stack.push(data)
elif operation == '3':
a_stack.display()
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 17 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
Queue
Queue is a linear data structure that permits insertion of new element at one end and
deletion of an element at the other end.
The end at which insertion of a new element can take place is called ‘ rear ‘ and the end at
which deletion of an element take place is called ‘ front ‘.
The first element that gets added into queue is the first one to get removed from the list,
Hence Queue is also referred to as First-In-First-Out ( FIFO ) list.
Queue must be created as empty.
Whenever an element is inserted into queue, it must be checked whether the queue is full
or not.
Whenever an element is deleted form queue, it must be checked whether the queue is
empty or not.
We can implement the queue ADT either with array or linked list.
Problem Solution
1. Create a class Queue with instance variable items initialized to an empty list.
2. Define methods enqueue, dequeue and is_empty inside the class Queue.
3. The method enqueue appends data to items.
4. The method dequeue dequeues the first element in items.
5. The method is_empty returns True only if items is empty.
6. Create an instance of Queue and present a menu to the user to perform operations on the
queue.
def is_empty(self):
return self.items == []
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 18 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
def dequeue(self):
return self.items.pop(0)
q = Queue()
while True:
print('1.Enqueue')
print('2.Dequeue')
print('3.Display')
print('4.Quit')
operation = input('What would you like to do? ')
if operation == '1':
val = input('Enter the value ')
q.enqueue(val)
elif operation == '2':
if q.is_empty():
print('Queue is empty.')
else:
print('Dequeued value:', q.dequeue())
elif operation == '3':
print('Queue values are:', q.display())
elif operation == '4':
break
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 1
Enter the value 10
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 1
Enter the value 20
1.Enqueue
2.Dequeue
3.Display
4.Quit
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 19 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
4.Quit
What would you like to do? 1
Enter the value 30
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 1
Enter the value 40
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 3
Queue values are: ['10', '20', '30', '40']
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 2
Dequeued value: 10
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 3
Queue values are: ['20', '30', '40']
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 1
Enter the value 45
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 3
Queue values are: ['20', '30', '40', '45']
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 4
In [ ]: #Queue Data Structure using Linked List
class Node:
def __init__(self, data):
self.data = data
self.next = None
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 20 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
class Queue:
def __init__(self):
self.head = None
self.last = None
def dequeue(self):
if self.head is None:
return None
else:
to_return = self.head.data
self.head = self.head.next
return to_return
def display(self):
if self.head is None:
print("Queue is empty")
else:
print("Elements in the list are: ")
p = self.head
while p is not None:
print(p.data)
p = p.next
print()
a_queue = Queue()
while True:
print('1.Enqueue')
print('2.Dequeue')
print('3.Display')
print('4.Quit')
operation = input('What would you like to do? ')
if operation == '1':
data = int(input("Enter the element to be inserted:"))
a_queue.enqueue(data)
elif operation == '3':
a_queue.display()
print('Queue is empty.')
else:
print('Dequeued element: ', int(dequeued))
elif operation == '4':
break
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 1
Enter the element to be inserted:11
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 1
Enter the element to be inserted:22
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 1
Enter the element to be inserted:33
1.Enqueue
2.Dequeue
3.Display
4.Quit
What would you like to do? 1
Enter the element to be inserted:44
1.Enqueue
2.Dequeue
3.Display
4.Quit
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 22 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
Applications of Queue
Due to the fact that queue performs actions on first in first out basis which is quite fair for the
ordering of actions. There are various applications of queues discussed as below.
Queues are widely used as waiting lists for a single shared resource like printer, disk, CPU.
Queues are used in asynchronous transfer of data (where data is not being transferred at
the same rate between two processes) for eg. pipes, file IO, sockets.
Queues are used as buffers in most of the applications like MP3 media player, CD player,
etc.
Queue are used to maintain the play list in media players in order to add and remove the
songs from the play-list.
Queues are used in operating systems for handling interrupts.
A queue has FIFO (first-in-first-out) ordering where items are taken out or accessed on a first-
come-first-served basis. Examples of queues include a queue at a movie ticket stand, as shown
in the illustration above. But, what is a priority queue?
A priority queue is an abstract data structure (a data structure defined by its behaviour) that is
like a normal queue but where each item has a special “key” to quantify its “priority”.A priority
queue is commonly used for dealing with scheduling problems. It gives precedence to tasks
with higher urgency.
For example, if the movie cinema decides to serve loyal customers first, it will order them by
their loyalty (points or number of tickets purchased). In such a case, the queue for tickets will no
longer be first-come-first-served, but most-loyal-first-served. The customers will be the “items”
of this priority queue while the “priority” or “key” will be their loyalty.
1) An element with high priority is dequeued before an element with low priority.
2) If two elements have the same priority, they are served according to their order in the queue.
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 23 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
(1, 'kotlin')
(3, 'java')
(5, 'Python')
student = []
student.append((5, 'python'))
student.append((1, 'java'))
student.append((3, 'kotlin'))
student.sort(reverse=True)
while student:
t = student.pop(0)
print(t)
(5, 'python')
(3, 'kotlin')
(1, 'java')
Let us see how we can implement Priority queue using a Python library.
Python provides a built-in implementation of a priority queue. The queue module is imported
and the elements are inserted using the put() method. The while loop is used to dequeue the
elements using the get() method.
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 24 of 25
stacks and Queue using List and Linked List_new - Jupyter Notebook 10/5/23, 10)23 AM
(4, 'Python')
(5, 'Java')
(8, 'Kotlin')
(10, 'Nodejs')
http://localhost:8888/notebooks/DSP/stacks%20and%20Queue%20using%20List%20and%20Linked%20List_new.ipynb Page 25 of 25