There are two ways to implement a stack:
Pros: Easy to implement. Memory is saved as pointers are not involved.
Cons: It is not dynamic. It doesn’t grow and shrink depending on needs at runtime.
class Queue:
def __init__(self):
self.queue = []
def is_empty(self):
return len(self.queue) == 0
def enqueue(self, data):
self.queue.append(data)
def dequeue(self):
if(self.is_empty()):
return "Empty Queue"
return self.queue.pop(0)
def front(self):
if(self.is_empty()):
return "Empty Queue"
return self.queue[0]
def rear(self):
if(self.is_empty()):
return "Empty Queue"
return self.queue[-1]
print("Example:- Array Implementation of Queue.")
my_queue = Queue()
print("Enqueue: 10, 20, 30, 40 to queue.")
my_queue.enqueue(10)
my_queue.enqueue(20)
my_queue.enqueue(30)
my_queue.enqueue(40)
print("Dequeue the first element: {}".format(my_queue.dequeue()))
print("Front element in queue: {}".format(my_queue.front()))
print("Rear element in queue: {}".format(my_queue.rear()))
print("Is queue empty? {}".format(my_queue.is_empty()))
Output:
Pros: The linked list implementation of stack can grow and shrink according to the needs at runtime.
Cons: Requires extra memory due to involvement of pointers.
class QueueNode:
def __init__(self, data):
self.data = data
self.next = None
class Queue:
def __init__(self):
self.head = None
def is_empty(self):
return True if self.head is None else False
def enqueue(self, data):
new_queue_node = QueueNode(data)
new_queue_node.next = self.head
self.head = new_queue_node
def dequeue(self):
if(self.is_empty()):
return "Empty Queue"
if(self.head.next is None):
dequeued_data = self.head.data
self.head = None
return dequeued_data
temp = self.head
while(temp.next.next):
temp = temp.next
dequeued_data = temp.next.data
temp.next = None
return dequeued_data
def front(self):
if(self.is_empty()):
return "Empty Queue"
temp = self.head
while(temp.next):
temp = temp.next
return temp.data
def rear(self):
if(self.is_empty()):
return "Empty Queue"
return self.head.data
print("Example:- LinkedList Implementation of Queue.")
my_queue = Queue()
print("Enqueue: 10, 20, 30, 40 to queue.")
my_queue.enqueue(10)
my_queue.enqueue(20)
my_queue.enqueue(30)
my_queue.enqueue(40)
print("Dequeue the first element: {}".format(my_queue.dequeue()))
print("Front element in queue: {}".format(my_queue.front()))
print("Rear element in queue: {}".format(my_queue.rear()))
print("Is queue empty? {}".format(my_queue.is_empty()))
Output:
Given a stack data structure with push and pop operations.
The task is to implement a queue using instances of stack data structure and operations on them.
from queue import LifoQueue
class Queue:
def __init__(self):
self.stack1 = LifoQueue()
self.stack2 = LifoQueue()
def enqueue(self, data):
# (1) Put all the data first to stack2
while(not self.stack1.empty()):
self.stack2.put(self.stack1.get())
# (2) Put the current data also to stack2
self.stack2.put(data)
# (3) Move evrything back to stack1 from stack2
while(not self.stack2.empty()):
self.stack1.put(self.stack2.get())
def dequeue(self):
if(self.stack1.empty()):
print("Empty Queue")
return
else:
return self.stack1.get()
def front(self):
if(self.stack1.empty()):
print("Empty Queue")
return
else:
return self.stack1.queue[-1]
def rear(self):
if(self.stack1.empty()):
print("Empty Queue")
return
else:
return self.stack1.queue[0]
def is_empty(self):
return self.stack1.empty()
print("Example:- Queue Using Stacks:")
my_queue = Queue()
print("Enqueue: 3, 1, 2, 4 to queue.")
my_queue.enqueue(3)
my_queue.enqueue(1)
my_queue.enqueue(2)
my_queue.enqueue(4)
my_queue.enqueue(6)
print("6 is enqueued to the queue.\n")
print("Dequeue the element: {}".format(my_queue.dequeue()))
print("Front element in queue: {}".format(my_queue.front()))
print("Rear element in queue: {}".format(my_queue.rear()))
print("Is queue empty? {}".format(my_queue.is_empty()))
Output:
Given a queue data structure that supports standard operations like enqueue() and dequeue().
The task is to implement a stack data structure using only instances of queue and queue operations allowed on the instances.
from queue import Queue
class Stack:
def __init__(self):
self.queue1 = Queue()
self.queue2 = Queue()
def push(self, data):
# (1) Put the data first to queue2
self.queue2.put(data)
# (2) Put all the data from queue1 to queue2
while(not self.queue1.empty()):
self.queue2.put(self.queue1.get())
# (3) Swap the names of two queues
self.queue1, self.queue2 = self.queue2, self.queue1
def pop(self):
if(self.queue1.empty()):
print("Stack Underflow")
return
else:
return self.queue1.get()
def top(self):
if(self.queue1.empty()):
print("Stack Underflow")
return
else:
return self.queue1.queue[0]
def is_empty(self):
return self.queue1.empty()
print("Example:- Stack Using Queues:")
my_stack = Stack()
print("Pushed: 4, 2, 1, 3 to stack.")
my_stack.push(4)
my_stack.push(2)
my_stack.push(1)
my_stack.push(3)
my_stack.push(6)
print("6 is pushed to the stack.\n")
print("Pop the first element: {}".format(my_stack.pop()))
print("Top element in stack: {}".format(my_stack.top()))
print("Is stack empty? {}".format(my_stack.is_empty()))
Output:
Example:
Input: {4, 6}, {6, 5}, {7, 3} and {4, 5}. // 4 petrol pumps with amount of petrol and distance to next petrol pump
Output: 2 // The first point from where truck can make a circular tour is 2nd petrol pump.
def first_circular_tour_visiting_all_pumps(pumps):
n = len(pumps)
# Consider first petrol pump as starting point
start = 0
end = 1
curr_petrol = pumps[start][0] - pumps[start][1]
# Run a loop while all petrol pumps are not visited
while(end != start):
# While curr_petrol is < 0, dequeue till it become positive.
while(curr_petrol<0 and start!=end):
# Remove starting petrol pump. Change start
curr_petrol -= pumps[start][0] - pumps[start][1]
start = (start +1)%n
# If 0 is being considered as start again, then there is no possible solution
if start == 0:
return -1
# Add a petrol pump to current tour
curr_petrol += pumps[end][0] - pumps[end][1]
end = (end +1) % n
return start+1
print("Example-1: first_circular_tour_visiting_all_pumps()")
pumps = [(4, 6), (6, 5), (7, 3), (4, 5)]
print(first_circular_tour_visiting_all_pumps(pumps))
print("Example-2: first_circular_tour_visiting_all_pumps()")
pumps = [(4, 6), (6, 5), (3, 5), (10, 5)]
print(first_circular_tour_visiting_all_pumps(pumps))
Output:
Given an array an integer k, find the maximum for each and every contiguous subarrays of size k.
Examples:
Input: 1, 2, 3, 1, 4, 5, 2, 3, 6 and k=3
Output: 3, 3, 4, 5, 5, 5, 6
Input: 8, 5, 10, 7, 9, 4, 15, 12, 90, 13 and k=4
Output: 10, 10, 10, 15, 15, 90, 90
def max_of_all_subarrays_of_k_size(arr, k):
n = len(arr)
max_subarray = []
# Initially current window
current_window = arr[:k]
# First get the initial current_window of of first k elements,
# the first element of max_subarray is max of initial window.
max_subarray.append(max(current_window))
# Now start from k+1th element, and in current_window
# dequeue the first element from current_window and enqueue the k+1th element
# get max of current_window and put in max_subarray and continue till the last element.
for i in range(k, n):
# Dequeue the first element and enqueue the next element
current_window.pop(0)
current_window.append(arr[i])
max_subarray.append(max(current_window))
return max_subarray
print("Example-1: max_of_all_subarrays_of_k_size")
arr = [1, 2, 3, 1, 4, 5, 2, 3, 6]
print(max_of_all_subarrays_of_k_size(arr, 3))
print("\nExample-2: max_of_all_subarrays_of_k_size")
arr = [8, 5, 10, 7, 9, 4, 15, 12, 90, 13]
print(max_of_all_subarrays_of_k_size(arr, 4))
Output:
Given a number n, write a function that generates and prints all binary numbers with decimal values from 1 to n.
Examples:
Input: n = 2
Output: 1, 10
Input: n = 5
Output: 1, 10, 11, 100, 101
def generate_1_to_n_binary_using_queue(n):
binary = []
queue = ["1"]
while(n > 0):
# Dequeue from the queue, add current to the list of binary numbers, then
# append "0" to it and enqueue and again append "1" to it and enqueue to queue
current = queue.pop(0)
binary.append(current)
queue.append(current+"0")
queue.append(current+"1")
n -= 1
return binary
print("Example-1: generate_1_to_n_binary_using_queue(5)")
print(generate_1_to_n_binary_using_queue(5))
print("\nExample-2: generate_1_to_n_binary_using_queue(10)")
print(generate_1_to_n_binary_using_queue(10))
← Previous: Stack Next: Matrix →