DS-Python-chapter-2-notes
DS-Python-chapter-2-notes
Syllabus :
2.1 Arrays – Overview, Types of Arrays, Operations on Arrays, Arrays vs List
2.2 Linked List – Overview, Implementation of Singly Linked Lists, Doubly Linked
Lists, Circular Linked Lists.
2.3 Stack - Overview of Stack, Implementation of Stack, Applications of Stack
(expression evaluation)
2.4 Queue-Overview of Queue, Implementation of Queue, Applications of Queues,
Types of Queues
2.1 Arrays
An array is a data structure that stores elements of the same data type in contiguous memory
locations. It allows efficient random access and manipulation of elements using their indices.
Features of Arrays
1. Fixed Size: The size of an array is determined at the time of creation and cannot be
modified.
2. Homogeneous Elements: All elements in the array are of the same data type.
3. Indexing: Elements are accessed using zero-based indexing.
4. Efficient Memory Utilization: Memory is allocated contiguously, which improves
access time.
Applications of Arrays
• Storing and accessing data in fixed-size datasets (e.g., student grades, RGB pixel
values).
• Used in matrix operations, search algorithms, and sorting algorithms.
Types of Arrays
1. One-Dimensional Array
o Represents a linear list of elements.
o Example: A=[10,20,30,40,50]A = [10, 20, 30, 40, 50]A=[10,20,30,40,50]
2. Two-Dimensional Array
o Represents a table or matrix with rows and columns.
o Example: B=[123456789]B = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9
\end{bmatrix}B=147258369
3. Multi-Dimensional Array
o Arrays with more than two dimensions, used for complex data representation
like tensors in machine learning.
4. Dynamic Arrays
o Arrays that can grow or shrink in size, such as Python’s list.
Operations on Arrays
1. Insertion
o Adding an element to a specific position in the array.
o Example: Insert 15 at index 2.
Before: [10, 20, 30, 40]
After: [10, 20, 15, 30, 40]
2. Deletion
o Removing an element from a specific position.
o Example: Delete the element at index 3.
Before: [10, 20, 30, 40]
After: [10, 20, 30]
3. Traversal
o Accessing each element of the array sequentially.
o Example: Iterating through [10, 20, 30, 40].
4. Searching
o Finding the position of a given element.
o Example: Search for 30 in [10, 20, 30, 40] → Index: 2.
5. Sorting
o Arranging elements in ascending or descending order.
o Example: Sort [30, 10, 40, 20] → [10, 20, 30, 40].
6. Updating
o Modifying the value of an existing element.
o Example: Update the value at index 1 to 25.
Before: [10, 20, 30]
After: [10, 25, 30]
Arrays vs Lists
Feature Arrays Lists
Data Type Homogeneous (same type) Heterogeneous (mixed types allowed)
Size Fixed Dynamic (can grow/shrink)
Memory Usage Less (contiguous memory) More (due to overhead)
Performance Faster (efficient memory access) Slower (due to type checking)
Implementation Direct support (e.g., NumPy) Built-in Python list
Array Implementation in Python
Python doesn’t have a built-in array type like C or Java. Instead, it uses:
• array module: For homogeneous arrays.
• numpy library: For more advanced array operations.
# Access elements
print(arr[0]) # Output: 10
# Insert element
arr.insert(2, 15) # Insert 15 at index 2
print(arr) # Output: array('i', [10, 20, 15, 30, 40])
# Remove element
arr.remove(30) # Remove the value 30
print(arr) # Output: array('i', [10, 20, 15, 40])
# Traverse
for element in arr:
print(element)
import numpy as np
# Create a 1D array
arr = np.array([10, 20, 30, 40])
# Access elements
print(arr[1]) # Output: 20
# Insert element (not in-place)
arr = np.insert(arr, 2, 15) # Insert 15 at index 2
print(arr) # Output: [10, 20, 15, 30, 40]
# Perform operations
print(np.sum(arr)) # Sum of elements
print(np.mean(arr)) # Mean of elements
class Array:
def __init__(self):
"""Initialize an empty list to represent the array."""
self.data = []
def display(self):
"""Display all elements in the array."""
return self.data
def size(self):
"""Return the number of elements in the array."""
return len(self.data)
def clear(self):
"""Clear all elements in the array."""
self.data.clear()
def menu():
print("\n--- Array Operations Menu ---")
print("1. Create an array")
print("2. Append an element")
print("3. Insert an element")
print("4. Delete an element")
print("5. Get an element by index")
print("6. Update an element by index")
print("7. Search for an element")
print("8. Display the array")
print("9. Get the size of the array")
print("10. Clear the array")
print("0. Exit")
print("-----------------------------")
if __name__ == "__main__":
arr = Array()
while True:
menu()
choice = input("Enter your choice: ")
try:
if choice == "1":
size = int(input("Enter the size of the array: "))
default_value = int(input("Enter the default value
(default is 0): "))
arr.create(size, default_value)
print(f"Array of size {size} created with default value
{default_value}.")
else:
print("Invalid choice! Please try again.")
except Exception as e:
print(f"Error: {e}")
Output:
# Example usage
sll = SinglyLinkedList()
sll.insert_at_beginning(10)
sll.insert_at_end(20)
sll.insert_at_end(30)
sll.display() # Output: 10 -> 20 -> 30 -> None
# Example usage
dll = DoublyLinkedList()
dll.insert_at_beginning(10)
dll.insert_at_end(20)
dll.insert_at_end(30)
dll.display() # Output: 10 <-> 20 <-> 30 <-> None
# Example usage
cll = CircularLinkedList()
cll.insert_at_end(10)
cll.insert_at_end(20)
cll.insert_at_end(30)
cll.display() # Output: 10 -> 20 -> 30 -> (Back to Head)
Applications of Stack
1. Expression Evaluation and Conversion:
o Converting infix expressions to postfix or prefix.
o Evaluating postfix or prefix expressions.
2. Backtracking:
o Navigating undo operations in applications.
o Solving puzzles like mazes and the Tower of Hanoi.
3. Parenthesis Matching:
o Checking balanced parentheses in expressions.
4. Function Call Management:
o Maintaining function calls in recursion using the call stack.
5. Parsing and Compilers:
o Syntax checking during code compilation.
Implementation of Stack
Stacks can be implemented in various ways, such as using arrays, Python lists, or linked lists.
def pop(self):
"""Pop the top element from the stack."""
if self.is_empty():
raise IndexError("Stack underflow: Cannot pop from an
empty stack")
return self.stack.pop()
def peek(self):
"""Peek at the top element of the stack without removing it."""
if self.is_empty():
raise IndexError("Stack is empty: Cannot peek")
return self.stack[-1]
def is_empty(self):
"""Check if the stack is empty."""
return len(self.stack) == 0
def size(self):
"""Return the size of the stack."""
return len(self.stack)
def display(self):
"""Display all elements in the stack."""
if self.is_empty():
return "Stack is empty"
return self.stack[::-1] # Reverse order to show stack's top at
the beginning
def menu():
print("\n--- Stack Operations Menu ---")
print("1. Push an element")
print("2. Pop an element")
print("3. Peek at the top element")
print("4. Check if the stack is empty")
print("5. Get the size of the stack")
print("6. Display the stack")
print("0. Exit")
print("-----------------------------")
if __name__ == "__main__":
stack = Stack()
while True:
menu()
choice = input("Enter your choice: ")
try:
if choice == "1":
value = int(input("Enter the value to push: "))
stack.push(value)
print(f"{value} pushed onto the stack.")
else:
print("Invalid choice! Please try again.")
except Exception as e:
print(f"Error: {e}")
Output:
class Stack:
def __init__(self):
self.top = None
def pop(self):
if self.is_empty():
return "Stack is empty"
popped_data = self.top.data
self.top = self.top.next
return popped_data
def peek(self):
if self.is_empty():
return "Stack is empty"
return self.top.data
def is_empty(self):
return self.top is None
def display(self):
temp = self.top
while temp:
print(temp.data, end=" -> ")
temp = temp.next
print("None")
# Example usage
s = Stack()
s.push(10)
s.push(20)
s.push(30)
print("Top Element:", s.peek()) # Output: Top Element: 30
s.pop()
s.display() # Output: 20 -> 10 -> None
return stack[0]
# Example usage
expression = "5 6 + 2 * 12 /"
result = evaluate_postfix(expression)
print("Result:", result) # Output: Result: 1.8333333333333333
2.4 Queue
Overview of Queue
A queue is a linear data structure that follows the First In, First Out (FIFO) principle. In this
structure, the first element added is the first one to be removed, similar to a line of people
waiting for a service.
Key Operations in a Queue
1. Enqueue: Add an element to the rear of the queue.
2. Dequeue: Remove an element from the front of the queue.
3. Peek (or Front): View the front element without removing it.
4. IsEmpty: Check if the queue is empty.
5. Size: Get the number of elements in the queue.
Applications of Queues
1. Task Scheduling:
o Managing tasks in operating systems (CPU scheduling, Disk scheduling).
o Print job management in printers.
2. Customer Service Systems:
o Handling requests in call centers or help desks.
3. Data Transmission:
o Queuing packets in network routers.
4. Breadth-First Search (BFS):
o Used in graph traversal algorithms.
5. Simulation Problems:
o Traffic management or waiting line simulations.
Types of Queues
1. Simple Queue (Linear Queue):
o Follows FIFO.
o Operations are performed at two ends (enqueue at rear, dequeue at front).
2. Circular Queue:
o The last position is connected to the first, forming a circle.
o Avoids wastage of space in the array implementation of queues.
3. Priority Queue:
o Elements are dequeued based on priority, not on arrival order.
oUsed in tasks like Dijkstra's algorithm.
4. Double-Ended Queue (Deque):
o Insertion and deletion can be performed at both ends.
o Comes in two variants:
▪ Input-Restricted Deque: Insertions are restricted to one end.
▪ Output-Restricted Deque: Deletions are restricted to one end.
Implementation of Queue
Queues can be implemented using arrays, Python lists, or linked lists.
def dequeue(self):
if not self.is_empty():
return self.queue.pop(0)
else:
return "Queue is empty"
def peek(self):
if not self.is_empty():
return self.queue[0]
else:
return "Queue is empty"
def is_empty(self):
return len(self.queue) == 0
def size(self):
return len(self.queue)
def display(self):
print(self.queue)
# Example usage
q = Queue()
q.enqueue(10)
q.enqueue(20)
q.enqueue(30)
print("Front Element:", q.peek()) # Output: Front Element: 10
q.dequeue()
q.display() # Output: [20, 30]
class Queue:
def __init__(self):
self.front = None
self.rear = None
def dequeue(self):
if self.front is None:
return "Queue is empty"
temp = self.front
self.front = temp.next
if self.front is None:
self.rear = None
return temp.data
def peek(self):
if self.front is None:
return "Queue is empty"
return self.front.data
def is_empty(self):
return self.front is None
def display(self):
temp = self.front
while temp:
print(temp.data, end=" -> ")
temp = temp.next
print("None")
# Example usage
q = Queue()
q.enqueue(10)
q.enqueue(20)
q.enqueue(30)
print("Front Element:", q.peek()) # Output: Front Element: 10
q.dequeue()
q.display() # Output: 20 -> 30 -> None
def dequeue(self):
if self.front == -1:
print("Queue is Empty")
elif self.front == self.rear:
temp = self.queue[self.front]
self.front = self.rear = -1
return temp
else:
temp = self.queue[self.front]
self.front = (self.front + 1) % self.size
return temp
def display(self):
if self.front == -1:
print("Queue is Empty")
elif self.rear >= self.front:
print(" ".join(map(str, self.queue[self.front : self.rear +
1])))
else:
print(" ".join(map(str, self.queue[self.front :] + self.queue[:
self.rear + 1])))
# Example usage
cq = CircularQueue(5)
cq.enqueue(10)
cq.enqueue(20)
cq.enqueue(30)
cq.display() # Output: 10 20 30
cq.dequeue()
cq.display() # Output: 20 30
Question Bank
Question Bloom's CO
Level Mapping
Define an array. Give an example of how arrays are Remembering CO1
used in real-life applications.
Explain the difference between a singly linked list and Understanding CO2
a doubly linked list.
What is the key principle of a stack? Illustrate with an Understanding CO2
example.
Describe the FIFO property of a queue with an Understanding CO3
example.
Write the syntax to declare an array in Python. Remembering CO1
Mention two advantages of using a circular queue over Understanding CO3
a simple queue.
What is the primary use of a priority queue? Understanding CO4
Compare the time complexities of stack operations: Analyzing CO2
Push and Pop.
3.5-Marks Questions
Question Bloom's CO
Level Mapping
Implement a Python program to find the maximum Applying CO1
element in an array.
Illustrate with code how to insert a node into a singly Applying CO2
linked list.
Explain with examples the real-life applications of stacks Analyzing CO2
in expression evaluation.
Write a Python function to check if a queue is empty or Applying CO3
full in a circular queue.
Compare arrays and linked lists in terms of memory usage Analyzing CO1, CO2
and performance.
Design a priority queue to store tasks with different Creating CO4
urgency levels and explain how tasks are dequeued.
Explain with code how to reverse a stack using recursion. Applying CO2
Analyze the differences between deque and a circular Analyzing CO3, CO4
queue with examples.
Question Bloom's CO
Level Mapping
Write a Python program to merge two arrays and sort the Applying CO1
resulting array in ascending order.
Explain with an example how to delete a node from the Applying CO2
middle of a singly linked list.
Discuss the process of evaluating a postfix expression Analyzing CO2
using a stack. Provide an example.
Write a Python function to implement a circular queue Applying CO3
with enqueue and dequeue operations.
Compare stacks and queues in terms of their Analyzing CO2, CO3
applications and data handling techniques.
Explain the concept of dynamic memory allocation and Understanding CO2
how it is utilized in linked lists.
Describe in detail the real-world applications of queues, Understanding CO3, CO4
giving examples for at least two types of queues.
7-Marks Questions
Design and implement a Python program to reverse an array without Creating CO1
using an additional array.
Write a Python function to perform the following operations on a Creating CO2
doubly linked list: insert at the beginning, delete from the end, and
display the list.
Discuss how recursion can be used to implement a stack and write a Creating CO2
Python program for the same.
Explain the concept of circular queues with the help of an example. Applying CO3
Write a Python program to demonstrate the enqueue and dequeue
operations in a circular queue.
Analyze the advantages and disadvantages of arrays and linked lists. Evaluating CO1,
Which data structure is better for dynamic data, and why? CO2
Design a priority queue for a hospital system where patients are Creating CO4
treated based on urgency. Explain the algorithm and implement it in
Python.
Compare and contrast the use of stacks and queues in solving real- Evaluating CO2,
world problems, providing examples for both. CO3
Question Bloom's CO
Level Mapping
Design and implement a Python program to create a menu-driven Creating CO1
system for array operations, including insertion, deletion, searching,
and sorting. Explain the logic behind each operation.
Write a Python program to implement a doubly linked list with the Creating CO2
following operations: insertion at the beginning, insertion at a specific
position, deletion from the end, and displaying the list in reverse order.
Discuss the time complexity of each operation.
Discuss the concept of stack-based expression evaluation. Write a Creating, CO2
Python program to evaluate an infix expression by converting it into a Analyzing
postfix expression and then evaluating it using a stack. Provide an
example and step-by-step explanation.
Compare and contrast the different types of queues (simple queue, Analyzing, CO3,
circular queue, and priority queue) in terms of their functionality, use Creating CO4
cases, and implementation complexities. Write Python code to
demonstrate the operations of a priority queue.
Analyze and implement a Python program to manage a print queue Evaluating, CO3,
system using a circular queue, where tasks are prioritized based on Creating CO4
arrival time and priority. Discuss the challenges in designing such a
system.
Describe in detail the memory management techniques used in linked Understand CO2
lists compared to arrays. Implement a Python program to create a ing,
linked list that supports dynamic memory allocation for insertion and Creating
deletion at any position.
Design a Python-based library management system that uses stacks Creating, CO3,
and queues for book borrowing and returning. Provide a detailed Evaluating CO4
explanation of the data structures used and the logic behind each
operation.