Module-3 Q&a
Module-3 Q&a
Levels ks
Module-3
1) Write a C++ function to perform the insert and delete operation of the queue
using arrays.
#include <iostream>
using namespace std;
int queue[100], n = 100, front = - 1, rear = - 1;
void Insert() {
int val;
if (rear == n - 1)
cout<<"Queue Overflow"<<endl;
else {
if (front == - 1)
front = 0;
cout<<"Insert the element in queue : "<<endl;
cin>>val;
rear++;
queue[rear] = val;
}
}
void Delete() {
if (front == - 1 || front > rear) {
cout<<"Queue Underflow ";
CO3 L2 10M
return ;
} else {
cout<<"Element deleted from queue is : "<< queue[front] <<endl;
front++;;
}
}
void Display() {
if (front == - 1)
cout<<"Queue is empty"<<endl;
else {
cout<<"Queue elements are : ";
for (int i = front; i <= rear; i++)
cout<<queue[i]<<" ";
cout<<endl;
}
}
int main() {
int ch;
cout<<"1) Insert element to queue"<<endl;
cout<<"2) Delete element from queue"<<endl;
cout<<"3) Display all the elements of queue"<<endl;
cout<<"4) Exit"<<endl;
do {
cout<<"Enter your choice : "<<endl;
cin>>ch;
switch (ch) {
case 1: Insert();
break;
case 2: Delete();
break;
case 3: Display();
break;
case 4: cout<<"Exit"<<endl;
break;
default: cout<<"Invalid choice"<<endl;
}
} while(ch!=4);
return 0;
}
The provided C++ program simulates queue operations (insert, delete, and
display). If we input the values 10, 20, 30, 40, 50 through the "Insert"
option, the queue operates as follows:
Menu:
Inputs:
Choose Insert (1) five times to input 10, 20, 30, 40, 50.
3. Exit (4).
Final Output:
After taking the inputs 10, 20, 30, 40, 50 and performing operations as
described, the queue's operations produce:
// Node structure
struct Node {
int data;
Node* next;
};
int main() {
Queue q;
int choice, value;
cout << "1) Insert element to queue" << endl;
cout << "2) Delete element from queue" << endl;
cout << "3) Display all the elements of queue" << endl;
cout << "4) Exit" << endl;
do {
cout << "Enter your choice: ";
cin >> choice;
switch (choice) {
case 1:
cout << "Enter value to be inserted: ";
cin >> value;
q.Insert(value);
break;
case 2:
q.Delete();
break;
case 3:
q.Display();
break;
case 4:
cout << "Exiting..." << endl;
break;
default:
cout << "Invalid choice" << endl;
}
} while (choice != 4);
return 0;
}
Example Run:
Input:
1
10
1
20
1
30
3
2
3
4
Output:
3) Sketch a Queue Q what is the value of front and rear after each of these
operations:
i) Insert item 50
ii) Insert item 10
iii) Insert item 30
iv) Delete an item
v) Delete an item.
With the size of Q is 5 has three elements 20, 40 and 60, where front = 0 and
rear = 2.
Let's simulate the queue operations step by step, keeping track of the queue
elements, front, and rear values. The queue's size is 5, and it initially CO3 L2 10M
contains the elements [20, 40, 60], with front = 0 and rear = 2.
i) Insert item 50
1. Check if the queue is full: Since rear + 1 != front, the queue has
space.
2. Increment rear by 1 (from 3 to 4).
3. Insert 10 at rear = 4.
v) Delete an item
class Queue {
private:
CO3 L2 10M
int front, rear, size;
int *queue;
public:
Queue(int s) {
size = s;
front = rear = -1;
queue = new int[size];
}
// Enqueue operation
void enqueue(int value) {
if (rear == size - 1) {
cout << "Queue Overflow" << endl;
return;
}
if (front == -1) front = 0; // Initialize front during the first enqueue
rear++;
queue[rear] = value;
cout << value << " inserted into the queue." << endl;
}
// Dequeue operation
void dequeue() {
if (front == -1 || front > rear) {
cout << "Queue Underflow" << endl;
return;
}
cout << "Element " << queue[front] << " deleted from the queue." <<
endl;
front++;
}
// Display operation
void display() {
if (front == -1 || front > rear) {
cout << "Queue is empty" << endl;
return;
}
cout << "Queue elements: ";
for (int i = front; i <= rear; i++) {
cout << queue[i] << " ";
}
cout << endl;
}
~Queue() {
delete[] queue;
}
};
int main() {
int size, choice, value;
cout << "Enter the size of the queue: ";
cin >> size;
Queue q(size);
do {
cout << "\n1. Enqueue\n2. Dequeue\n3. Display\n4. Exit" << endl;
cout << "Enter your choice: ";
cin >> choice;
switch (choice) {
case 1:
cout << "Enter value to enqueue: ";
cin >> value;
q.enqueue(value);
break;
case 2:
q.dequeue();
break;
case 3:
q.display();
break;
case 4:
cout << "Exiting..." << endl;
break;
default:
cout << "Invalid choice!" << endl;
}
} while (choice != 4);
return 0;
}
OUTPUT:
Sample Output
Input:
1. Enqueue
2. Dequeue
3. Display
4. Exit
Enter your choice: 1
Enter value to enqueue: 10
Enter your choice: 1
Enter value to enqueue: 20
Enter your choice: 1
Enter value to enqueue: 30
Enter your choice: 3
Enter your choice: 2
Enter your choice: 3
Enter your choice: 4
Output:
Enter the size of the queue: 5
1. Enqueue
2. Dequeue
3. Display
4. Exit
Enter your choice: 1
Enter value to enqueue: 10
10 inserted into the queue.
To analyze and sketch the state of the queue Q and determine the values of
front and rear after each operation, let’s walk through the scenario step by step:
Initial Queue State
6) Define standard template library of queue and write C++ program for the same
to represent all the operation of the queue.
Standard Template Library (STL) - Queue
The Standard Template Library (STL) in C++ provides a pre-defined queue
class under the <queue> header. It supports the FIFO (First-In-First-Out)
data structure. The operations provided by the STL queue include:
1. push(): Adds an element to the back of the queue.
2. pop(): Removes the front element of the queue.
3. front(): Accesses the front element.
4. back(): Accesses the last element.
5. empty(): Checks if the queue is empty.
6. size(): Returns the number of elements in the queue.
int main() {
queue<int> q; // Create a queue of integers
int choice, value;
do {
cout << "\nQueue Operations using STL:" << endl;
cout << "1. Enqueue (push)" << endl;
cout << "2. Dequeue (pop)" << endl;
cout << "3. Display Front Element" << endl;
cout << "4. Display Rear Element" << endl;
cout << "5. Display Queue Size" << endl;
cout << "6. Check if Queue is Empty" << endl;
cout << "7. Exit" << endl;
switch (choice) {
case 1:
cout << "Enter the value to enqueue: ";
cin >> value;
q.push(value); // Enqueue operation
cout << value << " added to the queue." << endl;
break;
case 2:
if (!q.empty()) {
cout << "Dequeued element: " << q.front() << endl;
q.pop(); // Dequeue operation
} else {
cout << "Queue is empty. Cannot dequeue!" << endl;
}
break;
case 3:
if (!q.empty()) {
cout << "Front element: " << q.front() << endl;
} else {
cout << "Queue is empty." << endl;
}
break;
case 4:
if (!q.empty()) {
cout << "Rear element: " << q.back() << endl;
} else {
cout << "Queue is empty." << endl;
}
break;
case 5:
cout << "Queue size: " << q.size() << endl;
break;
case 6:
if (q.empty()) {
cout << "Queue is empty." << endl;
} else {
cout << "Queue is not empty." << endl;
}
break;
case 7:
cout << "Exiting..." << endl;
break;
default:
cout << "Invalid choice. Please try again." << endl;
}
} while (choice != 7);
return 0;
}
Sample Output
Input:
1. Enqueue (push)
2. Dequeue (pop)
3. Display Front Element
4. Display Rear Element
5. Display Queue Size
6. Check if Queue is Empty
7. Exit
int main() {
priority_queue<int> maxPQ; // Max Priority Queue
priority_queue<int, vector<int>, greater<int>> minPQ; // Min Priority
CO3 L2 10M
Queue
return 0;
}
Sample Output
Max Priority Queue: 20 10 5
Min Priority Queue: 5 10 20
Applications
• Task scheduling, graph algorithms (Dijkstra’s, Prim’s), real-time data
processing.
Complexity
• O(log n) for insertion and deletion.
8) Construct a C++ program that performs linear search using an array of integer
value and mention the time complexity of the linear search in best case, worst
case and average case.
Linear Search in C++
A linear search is a simple search algorithm that checks each element in a list
sequentially until the target element is found or the list ends.
C++ Program for Linear Search
#include <iostream>
using namespace std;
int main() {
int arr[] = {34, 7, 23, 32, 5, 62};
int size = sizeof(arr) / sizeof(arr[0]);
int target;
CO3 L3 10M
cout << "Enter the element to search: ";
cin >> target;
if (result != -1) {
cout << "Element " << target << " found at index " << result << endl;
} else {
cout << "Element " << target << " not found in the array." << endl;
}
return 0;
}
Explanation of the Program
1. Input:
o An array of integers arr[] is defined with values {34, 7, 23, 32,
5, 62}.
o The program takes an integer target as input, which is the value
to be searched in the array.
2. linearSearch() Function:
o The function iterates through the array to check if the element
matches the target.
o If the element is found, the index is returned.
o If the element is not found after checking all elements, -1 is
returned.
3. Output:
o If the element is found, the program prints the index where the
element is located.
o If the element is not found, it prints that the element is not in
the array.
Time Complexity of Linear Search
1. Best Case: O(1)
o The best case occurs when the target element is the first element
in the array. The search is completed in one step.
2. Worst Case: O(n)
o The worst case occurs when the target element is not present in
the array or is the last element. The entire array must be
searched, so it takes n comparisons.
3. Average Case: O(n)
o On average, the target element will be located in the middle of
the array. Therefore, half of the elements will be checked, but
the time complexity remains O(n) since constant factors are
ignored.
Sample Input and Output
Input:
Enter the element to search: 32
Output:
Element 32 found at index 3
Summary of Time Complexity
• Best Case: O(1)
• Worst Case: O(n)
• Average Case: O(n)
9) Write a C++ program that performs binary search using an array of real values.
Binary Search in C++
Binary Search is an efficient search algorithm that works on sorted arrays.
It repeatedly divides the search interval in half. If the value of the target is less
than the item in the middle of the interval, the search continues in the lower
half, otherwise, it continues in the upper half.
C++ Program for Binary Search
#include <iostream> CO3 L2 10M
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// Array of real numbers (sorted)
vector<double> arr = {1.5, 3.2, 5.6, 7.3, 8.0, 9.9, 12.4, 14.5, 16.2};
double target;
cout << "Enter the element to search: ";
cin >> target;
return 0;
}
Explanation of the Program
1. Input:
o The program defines a sorted array of real values (arr[]) with
values {1.5, 3.2, 5.6, 7.3, 8.0, 9.9, 12.4, 14.5, 16.2}.
o The user is prompted to enter a target value (target), which is
the number to search for in the array.
2. binarySearch() Function:
o The function takes a sorted array (arr[]), the size of the array
(size), and the target value (target).
o It initializes two indices: low (beginning of the array) and high
(end of the array).
o The algorithm keeps dividing the array in half and compares
the middle element (mid) with the target:
▪ If arr[mid] equals the target, the index mid is returned.
▪ If the target is smaller, the search continues in the left
half (high = mid - 1).
▪ If the target is larger, the search continues in the right
half (low = mid + 1).
o If the target is not found, it returns -1.
3. Output:
o If the element is found, the program prints the index where the
element is located.
o If the element is not found, it prints a message stating that the
element is not in the array.
Time Complexity of Binary Search
• Best Case: O(1) — The target is found at the middle element.
• Worst Case: O(log n) — The search space is halved at each step, so
the number of comparisons grows logarithmically with the size of the
array.
• Average Case: O(log n) — Like the worst case, binary search works
by halving the search space, regardless of where the element is located.
Sample Input and Output
Input:
Enter the element to search: 7.3
Output:
Element 7.3 found at index 3
Input:
Enter the element to search: 10.5
Output:
Element 10.5 not found in the array.
Summary
• Binary Search is highly efficient for searching in sorted arrays, with a
time complexity of O(log n) in both the worst and average cases.
• It is much faster than linear search for large datasets, especially when
the data is already sorted.
10) What is hashing? And explain the working and components of hashing with
CO3 L2 5M
an example.
Hashing
Hashing is a technique used to uniquely identify and store data in a table using
a hash function, which maps keys to hash values (indices). It allows for
efficient data retrieval.
Components of Hashing
1. Hash Function: A function that converts a key into an integer (hash
value). Example: hashValue = key % tableSize.
2. Hash Table: A data structure that stores elements at indices computed
by the hash function.
3. Collision Handling:
o Chaining: Store elements in a linked list at the same index.
o Open Addressing: Find another empty spot (e.g., linear
probing).
4. Buckets: Containers in the table where data is stored.
Working of Hashing
1. Insertion: The key is hashed, and the data is inserted at the
corresponding index in the hash table. If a collision occurs, it’s handled
by chaining or open addressing.
2. Search: The key is hashed, and the corresponding index is checked for
the presence of the element.
3. Deletion: The key is hashed, and the element is removed from the
corresponding index.
Example
For data elements 23, 45, 12, 17, 34 and a table size of 10, using hashValue =
key % 10, the elements are inserted at the following indices:
• 23 → index 3
• 45 → index 5
• 12 → index 2
• 17 → index 7
• 34 → index 4
If there’s a collision (e.g., inserting 15, which hashes to 5), chaining is used to
store 15 in the linked list at index 5.
C++ Code Example
#include <iostream>
#include <list>
using namespace std;
class HashTable {
int tableSize;
list<int>* table;
public:
HashTable(int size) {
tableSize = size;
table = new list<int>[tableSize];
}
int hashFunction(int key) {
return key % tableSize;
}
void display() {
for (int i = 0; i < tableSize; i++) {
cout << "Index " << i << ": ";
for (auto it : table[i]) {
cout << it << " -> ";
}
cout << "NULL" << endl;
}
}
};
int main() {
HashTable ht(10);
ht.insert(23);
ht.insert(45);
ht.insert(12);
ht.insert(17);
ht.insert(34);
ht.display();
return 0;
}
Time Complexity
• Average Case: O(1) for insertion, search, and deletion.
• Worst Case: O(n) when collisions cause long linked lists.
Hashing allows efficient data storage and retrieval, but collision handling is
essential for maintaining performance.
11) Explain the linear probing technique to overcome the collision in hashing and
write the C++ program for the same.
Linear Probing in Hashing
Linear Probing is a collision resolution technique used in hash tables. When
two or more keys hash to the same index (collision), linear probing searches
for the next available empty slot in the array to store the key. This technique
works by checking subsequent array locations in a linear fashion until an open
slot is found.
How Linear Probing Works
1. Insertion: When inserting a key, calculate the hash value. If the
position is occupied, check the next position, and repeat this process
until an empty slot is found.
2. Search: After calculating the hash, if the slot is occupied but the key is
not found, check the next slot, and continue searching until either the
key is found or an empty slot is reached.
3. Deletion: When deleting a key, remove it and rehash the subsequent
elements that were stored using linear probing.
Advantages of Linear Probing CO3 L2 10M
• Simple to implement.
• Efficient when the table has fewer collisions.
Disadvantages of Linear Probing
• Clustering: If many elements hash to the same location, it can lead to
"primary clustering," where groups of consecutive occupied slots form,
reducing efficiency.
• Performance degrades if the table is too full.
C++ Program Implementing Linear Probing
#include <iostream>
using namespace std;
class HashTable {
int* table;
int tableSize;
int currentSize;
public:
// Constructor
HashTable(int size) {
tableSize = size;
table = new int[tableSize];
currentSize = 0;
table[index] = key;
currentSize++;
}
cout << "Key " << key << " not found." << endl;
}
int main() {
HashTable ht(10);
// Inserting elements
ht.insert(15);
ht.insert(25);
ht.insert(35);
ht.insert(45);
ht.display();
// Removing an element
ht.remove(25);
ht.display();
return 0;
}
Explanation of the Program
1. Hash Table Initialization: The table is initialized with a fixed size (10
in this case), and each slot is initially set to -1 to indicate an empty slot.
2. Hash Function: The hash function key % tableSize is used to compute
the index for storing a key in the table.
3. Insertion: The insert() function calculates the hash index for a key. If
the slot is already occupied, it moves to the next slot using linear
probing until an empty slot is found.
4. Search: The search() function calculates the hash index and searches
for the key using linear probing. If the key is found, it returns true;
otherwise, it returns false.
5. Deletion: The remove() function deletes the key if found by linear
probing. After deletion, it adjusts the table by marking the slot as empty
(-1).
6. Display: The display() function prints all the non-empty elements in
the hash table.
Example Output
Index 0: Empty
Index 1: Empty
Index 2: Empty
Index 3: 15
Index 4: Empty
Index 5: 25
Index 6: Empty
Index 7: 35
Index 8: 45
Index 9: Empty
25 found!
Key 25 removed.
Index 0: Empty
Index 1: Empty
Index 2: Empty
Index 3: 15
Index 4: Empty
Index 5: Empty
Index 6: Empty
Index 7: 35
Index 8: 45
Index 9: Empty
Time Complexity
• Insertion: In the best case, the time complexity is O(1) if the hash
value maps to an empty slot. In the worst case, the time complexity
can become O(n) if many slots are occupied, and linear probing
searches the entire table.
• Search: Similar to insertion, in the best case, it takes O(1) time. In the
worst case, it can take O(n) time if the table is full and all elements
need to be checked.
• Deletion: The deletion process also involves linear probing, so the time
complexity is O(n) in the worst case if the element is found near the
end of the table.
13) Apply selection sort technique for the data: 74, 39, 35,32,97,84. Demonstrate
a C++ program for selection sort.
Selection Sort Explanation
Selection Sort is a simple comparison-based sorting algorithm. The algorithm
repeatedly selects the smallest (or largest, depending on the sorting order)
element from the unsorted portion of the list and swaps it with the first unsorted
element. The process continues until the entire list is sorted.
Steps of Selection Sort:
1. Start from the first element of the array.
2. Find the minimum (or maximum) element in the unsorted part of the
array.
3. Swap the minimum element with the element at the current position.
4. Move the boundary of the sorted part of the array one element forward.
5. Repeat the process until the entire array is sorted.
CO3 L2 10M
Selection Sort C++ Program
#include <iostream>
using namespace std;
int main() {
int arr[] = {74, 39, 35, 32, 97, 84};
int n = sizeof(arr) / sizeof(arr[0]);
selectionSort(arr, n);
return 0;
}
Explanation of the Code:
1. selectionSort function: This function sorts the array using the
selection sort technique. It iterates through each element, finds the
smallest element in the unsorted portion, and swaps it with the first
unsorted element.
2. displayArray function: This function prints the elements of the array.
3. main function: Initializes the array and calls both selectionSort and
displayArray to demonstrate the sorting process.
Output:
Array before sorting: 74 39 35 32 97 84
Array after sorting: 32 35 39 74 84 97
The time complexity of selection sort is O(n^2) in all cases because it always
performs two nested loops.
14) Define shell sort and also with C++ function to sort the array of integers using
shell sort.
Shell Sort:
CO3 L2 10M
Shell Sort is an algorithm that generalizes the insertion sort to allow the
exchange of items that are far apart. The idea is to arrange the elements of the
array in such a way that the elements that are far apart are compared and sorted
first. This reduces the number of inversions and brings the array closer to being
sorted.
The main idea behind Shell Sort is to use a gap sequence. The array is divided
into subarrays based on a gap, and insertion sort is applied to each of these
subarrays. Initially, the gap is large, and it reduces over time, eventually
performing an insertion sort on the entire array when the gap becomes 1.
Steps in Shell Sort:
1. Start by choosing an initial gap size. Typically, the gap starts as half
the size of the array.
2. For each gap, perform an insertion sort on the elements that are gap
distance apart.
3. Gradually reduce the gap until it becomes 1, at which point the array
will be fully sorted using a regular insertion sort.
C++ Program for Shell Sort:
#include <iostream>
using namespace std;
int main() {
int arr[] = {74, 39, 35, 32, 97, 84}; // Example array
int n = sizeof(arr) / sizeof(arr[0]); // Get the size of the array
return 0;
}
Explanation of the Code:
1. shellSort Function:
o The function begins with a large gap size (half the size of the
array) and iteratively reduces the gap by halving it each time.
o For each gap size, we perform a gapped insertion sort.
Elements are compared and swapped with a gap of gap
positions, which gradually moves the elements closer to their
final position.
2. printArray Function:
o This function simply prints the elements of the array.
3. Main Function:
o Initializes an example array of integers.
o Calls the shellSort function to sort the array.
o Prints the array before and after sorting.
Example Output:
Original Array: 74 39 35 32 97 84
Sorted Array: 32 35 39 74 84 97
Shell Sort is faster than basic insertion sort due to the reduced number of
comparisons and swaps, especially when the gap is large at the beginning.
However, its performance highly depends on the gap sequence chosen.