my_obsidian

git clone https://github.com/notamitgamer/my_obsidian.git
· rebuilt hourlyOpen on GitHub
root / assignment.md

assignment.md (135047B)


      1 <u><h1 align="center">INDEX</h1></u>
      2 
      3 | Serial No. | Problem Statement                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Page No. | Teacher's Signature |
      4 | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------- |
      5 | 1          | Write a program to implement a Diagonal Matrix, a Lower Triangular Matrix, an Upper Triangular Matrix, and a Symmetric Matrix using a one-dimensional array.                                                                                                                                                                                                                                                                                                                                                                                              | 2        |                     |
      6 | 2          | Write a program to search an element from a list. Give user the option to perform Linear or Binary search.                                                                                                                                                                                                                                                                                                                                                                                                                                                | 9        |                     |
      7 | 3          | WAP to sort a list of elements. Give user the option to perform sorting using Insertion sort, Bubble sort or Selection sort.                                                                                                                                                                                                                                                                                                                                                                                                                              | 15       |                     |
      8 | 4          | Implement Linked List. Include functions for insertion, deletion and search of a number, reverse the list and concatenate two linked lists (include a function and also overload operator +).                                                                                                                                                                                                                                                                                                                                                             | 21       |                     |
      9 | 5          | Implement Doubly Linked List. Include functions for insertion, deletion and search of a number, reverse the list.                                                                                                                                                                                                                                                                                                                                                                                                                                         | 31       |                     |
     10 | 6          | Implement Circular Linked List. Include functions for insertion, deletion and search of a number, reverse the list.                                                                                                                                                                                                                                                                                                                                                                                                                                       | 40       |                     |
     11 | 7          | Perform Stack operations using Linked List implementation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | 50       |                     |
     12 | 8          | Perform Stack operations using Array implementation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | 55       |                     |
     13 | 9          | Perform Queues operations using Array.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | 59       |                     |
     14 | 10         | Perform Circular Queues operations using Array.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | 64       |                     |
     15 | 11         | Perform Queues operations using linklist.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | 69       |                     |
     16 | 12         | Create and perform different operations on Double-ended Queues using Linked List implementation.                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 73       |                     |
     17 | 13         | WAP to scan a polynomial using linked list and add two polynomials.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | 79       |                     |
     18 | 14         | WAP to calculate factorial and to compute the factors of a given no. (i) using recursion, (ii) using iteration.                                                                                                                                                                                                                                                                                                                                                                                                                                           | 85       |                     |
     19 | 15         | WAP to display Fibonacci series (i) using recursion, (ii) using iteration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | 89       |                     |
     20 | 16         | WAP to create a Binary Search Tree and include following operations in tree: i. Insertion (Recursive and Iterative Implementation) ii. Deletion by copying iii. Deletion by Merging iv. Search a no. in BST v. Display its preorder, postorder and inorder traversals Recursively vi. Display its preorder, postorder and inorder traversals Iteratively vii. Display its level-by-level traversals viii. Count the non-leaf nodes and leaf nodes ix. Display height of tree x. Create a mirror image of tree xi. Check whether two BSTs are equal or not | 92       |                     |
     21 | 17         | WAP to convert the Sparse Matrix into non-zero form and vice-versa.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | 110      |                     |
     22 | 18         | WAP to reverse the order of the elements in the stack using additional stack.                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | 116      |                     |
     23 | 19         | WAP to reverse the order of the elements in the stack using additional Queue.                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | 120      |                     |
     24 ///
     25 ## Assignment 1
     26 
     27 ### Problem Statement: 
     28 Write a program to implement a Diagonal Matrix a Lower Triangular Matrix, an Upper Triangular Matrix, and a Symmetric Matrix using a one-dimensional array.
     29 
     30 ### Problem Defination: 
     31 Matrix memory optimization means storing special matrices efficiently by avoiding storage of predictable zero or duplicate elements, using compact 1D array instead of full 2D array.
     32 - **Diagonal Matrix:** Only diagonal elements `(i == j)` are non-zero. Stored using the formula `arr[i]`.
     33 - **Lower Triangular Matrix:** All elements above the main diagonal are zero. Non-zero elements mapped using `i*(i+1)/2 + j`.
     34 - **Upper Triangular Matrix:** All elements below the main diagonal are zero. Non-zero elements mapped using `n*i - i*(i-1)/2 + (j-i)`.
     35 - **Symmetric Matrix:** Matrix equal to its transpose `(A[i][j] = A[j][i])`. Only the lower triangular half is stored, using `i*(i+1)/2 + j`.
     36 
     37 ### Algorithm: 
     38 **Diagonal Matrix:** 
     39 ```
     40 procedure setDiagonal(arr, i, j, x)
     41 begin
     42 	if(i == j)
     43 		arr[i] <- x;
     44 	end if
     45 end procedure
     46 
     47 procedure getDiagonal(arr, i, j)
     48 begin
     49 	if(i == j)
     50 		return arr[i];
     51 	else
     52 		return 0;
     53 	end if
     54 end procedure
     55 ```
     56 
     57 **Lower Triangular Matrix:**
     58 ```
     59 procedure setLower(arr, i, j, x)
     60 begin
     61 	if(i >= j)
     62 		arr[i*(i+1)/2+j] <- x;
     63 	end if
     64 end procedure
     65   
     66 procedure getLower(arr, i, j)
     67 begin
     68 	if(i >= j)
     69 		return arr[i*(i+1)/2+j];
     70 	else
     71 		return 0;
     72 	end if
     73 end procedure
     74 ```  
     75 
     76 **Upper Triangular Matrix:**
     77 ```
     78 Procedure setUpper(arr, n, i, j, x)
     79 begin
     80 	if(i <= j)
     81 		arr[n*i-i*(i-1)/2+(j-i)] <- x;
     82 	end if
     83 end procedure
     84 
     85 Procedure getUpper(arr, n, i, j)
     86 begin
     87 	if(i <= j)
     88 		return arr[n*i-i*(i-1)/2+(j-i)];
     89 	else
     90 		return 0;
     91 	end if
     92 end procedure
     93 ```
     94 
     95 **Symmetric Matrix:**
     96 ```
     97 Procedure setSymmetric(arr, i, j, x)
     98 begin
     99 	if(i >= j)
    100 		arr[i*(i+1)/2+j] <- x;
    101 	else
    102 		arr[j*(j+1)/2+i] <- x;
    103 	end if
    104 end procedure
    105 
    106 Procedure getSymmetric(arr, i, j)
    107 begin
    108 	if(i >= j)
    109 		return arr[i*(i+1)/2+j];
    110 	else
    111 		return arr[j*(j+1)/2+i];
    112 	end if
    113 end procedure
    114 ```
    115 
    116 ///
    117 ### Source Code: 
    118 ```
    119 #include <iostream>
    120 
    121 using namespace std;
    122 
    123 class Matrix
    124 {
    125 private:
    126   int n, *arr;
    127 
    128 public:
    129   Matrix(int size)
    130   {
    131     n = size;
    132     arr = new int[n * (n + 1) / 2];
    133   }
    134 
    135   void setDiagonal(int i, int j, int x)
    136   {
    137     if (i == j)
    138       arr[i] = x;
    139   }
    140   void setLowerTri(int i, int j, int x)
    141   {
    142     if (i >= j)
    143       arr[i * (i + 1) / 2 + j] = x;
    144   }
    145   void setUpperTri(int i, int j, int x)
    146   {
    147     if (i <= j)
    148       arr[n * i - (i * (i - 1) / 2) + (j - i)] = x;
    149   }
    150   void setSymmetric(int i, int j, int x)
    151   {
    152     (i >= j) ? arr[i * (i + 1) / 2 + j] = x : arr[j * (j + 1) / 2 + i] = x;
    153   }
    154 
    155   int getDiagonal(int i, int j)
    156   {
    157     return (i == j) ? arr[i] : 0;
    158   }
    159   int getLowerTri(int i, int j)
    160   {
    161     return (i >= j) ? arr[i * (i + 1) / 2 + j] : 0;
    162   }
    163   int getUpperTri(int i, int j)
    164   {
    165     return (i <= j) ? arr[n * i - i * (i - 1) / 2 + (j - i)] : 0;
    166   }
    167   int getSymmetric(int i, int j)
    168   {
    169     return (i >= j) ? arr[i * (i + 1) / 2 + j] : arr[j * (j + 1) / 2 + i];
    170   }
    171 
    172   void display(int type)
    173   {
    174     cout << endl
    175          << "Matrix:" << endl;
    176     for (int i = 0; i < n; i++)
    177     {
    178       for (int j = 0; j < n; j++)
    179       {
    180         if (type == 1)
    181           cout << getDiagonal(i, j) << " ";
    182         else if (type == 2)
    183           cout << getLowerTri(i, j) << " ";
    184         else if (type == 3)
    185           cout << getUpperTri(i, j) << " ";
    186         else if (type == 4)
    187           cout << getSymmetric(i, j) << " ";
    188       }
    189       cout << endl;
    190     }
    191   }
    192 
    193   ~Matrix()
    194   {
    195     delete[] arr;
    196   }
    197 };
    198 
    199 int main()
    200 {
    201   int n, choice, x;
    202   cout << "Enter the order of the matrix : ";
    203   cin >> n;
    204   Matrix M(n);
    205 
    206   cout << "\n1. Diagonal Matrix.";
    207   cout << "\n2. Lower Triangular Matrix.";
    208   cout << "\n3. Upper Triangular Matrix.";
    209   cout << "\n4. Symmetric Matrix.";
    210   cout << "\nEnter your choice : ";
    211   cin >> choice;
    212 
    213   switch (choice)
    214   {
    215   case 1:
    216     cout << "\nEnter the diagonal elements : ";
    217     for (int i = 0; i < n; i++)
    218     {
    219       cin >> x;
    220       M.setDiagonal(i, i, x);
    221     }
    222     M.display(1);
    223     break;
    224 
    225   case 2:
    226     cout << "\nEnter the elements : ";
    227     for (int i = 0; i < n; i++)
    228     {
    229       for (int j = 0; j <= i; j++)
    230       {
    231         cin >> x;
    232         M.setLowerTri(i, j, x);
    233       }
    234     }
    235     M.display(2);
    236     break;
    237 
    238   case 3:
    239     cout << "\nEnter the elements : ";
    240     for (int i = 0; i < n; i++)
    241     {
    242       for (int j = i; j < n; j++)
    243       {
    244         cin >> x;
    245         M.setUpperTri(i, j, x);
    246       }
    247     }
    248     M.display(3);
    249     break;
    250 
    251   case 4:
    252     cout << "\nEnter the elements : ";
    253     for (int i = 0; i < n; i++)
    254     {
    255       for (int j = 0; j <= i; j++)
    256       {
    257         cin >> x;
    258         M.setSymmetric(i, j, x);
    259       }
    260     }
    261     M.display(4);
    262     break;
    263 
    264   default:
    265     cout << "Invalid Choice.";
    266   }
    267   return 0;
    268 }
    269 ```
    270 
    271 ### Output: 
    272 ![[Pasted image 20260922092253.png|431]]
    273 
    274 ![[Pasted image 20260922092306.png|431]]
    275 
    276 ### Discussion: 
    277 This program demonstrates how memory can be saved when working with special types of matrices — **Diagonal**, **Lower Triangular**, **Upper Triangular**, and **Symmetric** — by storing only their essential elements in a single dynamically allocated 1D array, rather than a full 2D array.
    278 
    279 A **Matrix** class is used to bundle together the storage (the array) and the logic needed to interpret it correctly for each matrix type.
    280   
    281 Two private members drive the class:
    282 
    283 - **arr** - a dynamically allocated integer pointer that holds the compact array of stored values.
    284 - **n** - the order (size) of the square matrix.
    285 
    286 When a **Matrix** object is created, the constructor computes the array size as **n*(n+1)/2** and allocates it on the heap using **new**.
    287 
    288 The class's functionality is built around these key methods:
    289 
    290 - **setDiagonal()**, **setLowerTri()**, **setUpperTri()** and **setSymmetric()** – Each of these accepts a row index, column index, and a value, then applies a matrix-specific formula to determine exactly where that value should be placed in the 1D array.
    291 - **getDiagonal()**, **getLowerTri()**, **getUpperTri()** and **getSymmetric()** – These reconstruct values for any **(i, j)** position by locating them in the array (using ternary conditions), returning 0 for positions that were never stored, and — in the Symmetric case — reflecting values across the diagonal when needed.
    292 - **display()** – Using two nested loops, this method walks through every position of the conceptual n×n matrix and prints the corresponding value, effectively rebuilding the full matrix view from the compact array.
    293 
    294 Finally, the destructor **~Matrix()** ensures proper cleanup by releasing the dynamically allocated array with **delete[]** once the object goes out of scope, preventing memory leaks.
    295 
    296 ///
    297 ## Assignment 2
    298 ### Problem Statement:
    299 Write a program to search an element from a list of elements using Linear Search and Binary Search techniques.
    300 
    301 ### Problem Defination:
    302 Searching is the process of finding whether a particular element is present in a given collection of elements, and if present, locating its position.
    303 
    304 - **Linear Search:** Examines each element of the list sequentially, one by one, starting from the first, until the desired element is found or the list ends. It works on both sorted and unsorted lists but has a time complexity of `O(n)`.
    305 - **Binary Search:** Works only on a sorted list. It repeatedly divides the search interval in half — comparing the key with the middle element and eliminating the half of the list where the key cannot exist — giving a time complexity of `O(log n)`.
    306 
    307 ### Algorithm:
    308 **Linear Search:**
    309 ```
    310 procedure linearSearch(arr, n, key)
    311 begin
    312 	for i ← 0 to n - 1 do
    313 		if(arr[i] = key)
    314 			return i;
    315 		end if
    316 	end for
    317 	return -1;
    318 end procedure
    319 ```
    320 
    321 **Binary Search:**
    322 ```
    323 procedure binarySearch(arr, n, key)
    324 begin
    325 	left ← 0;
    326 	right ← n - 1;
    327 	while(left <= right) do
    328 		mid ← left + (right - left) / 2;
    329 		if(arr[mid] = key)
    330 			return mid;
    331 		else if(arr[mid] < key)
    332 			left ← mid + 1;
    333 		else
    334 			right ← mid - 1;
    335 		end if
    336 	end while
    337 	return -1;
    338 end procedure
    339 ```
    340 
    341 ### Source Code:
    342 ```
    343 using namespace std;
    344 
    345 typedef struct MenuItem {
    346     int id;
    347     const char* name;
    348 } menu;
    349 
    350 class SearchList {
    351 private:
    352     int *arr;
    353     int n;
    354 
    355     void insertionSort() {
    356         for (int i = 1; i < n; i++) {
    357             int key = arr[i];
    358             int j = i - 1;
    359             while (j >= 0 && arr[j] > key) {
    360                 arr[j + 1] = arr[j];
    361                 j--;
    362             }
    363             arr[j + 1] = key;
    364         }
    365     }
    366 
    367 public:
    368     SearchList(int size) {
    369         n = size;
    370         arr = new int[n];
    371     }
    372 
    373     void inputElements() {
    374         cout << "\nEnter " << n << " elements: ";
    375         for (int i = 0; i < n; i++) {
    376             cin >> arr[i];
    377         }
    378     }
    379 
    380     int linearSearch(int key) {
    381         for (int i = 0; i < n; i++) {
    382             if (arr[i] == key) {
    383                 return i;
    384             }
    385         }
    386         return -1;
    387     }
    388 
    389     int binarySearch(int key) {
    390         
    391         insertionSort();
    392         cout << "\n(Array automatically sorted for Binary Search)";
    393         display();
    394 
    395         int left = 0;
    396         int right = n - 1;
    397 
    398         while (left <= right) {
    399             int mid = left + (right - left) / 2;
    400 
    401             if (arr[mid] == key) {
    402                 return mid;
    403             } else if (arr[mid] < key) {
    404                 left = mid + 1;
    405             } else {
    406                 right = mid - 1;
    407             }
    408         }
    409         return -1;
    410     }
    411 
    412     void display() {
    413         cout << "\nCurrent List: ";
    414         for (int i = 0; i < n; i++) {
    415             cout << arr[i] << " ";
    416         }
    417         cout << endl;
    418     }
    419 
    420     void printMenu() {
    421         menu items[] = {
    422             {1, "Linear Search"}, {2, "Binary Search"},
    423             {0, "Display List"},  {-1, "Exit"}
    424         };
    425 
    426         cout << "\n## Choose Search Method --\n--------------------------------------------\n";
    427         for (int i = 0; i < 4; i++) {
    428             cout << items[i].id << ". " << left << setw(20) << items[i].name;
    429             if (i % 2 == 1) cout << "\n";
    430         }
    431     }
    432 
    433     ~SearchList() {
    434         delete[] arr;
    435     }
    436 };
    437 
    438 int main() {
    439     int n, choice, key;
    440     cout << "Enter the size of the list: ";
    441     cin >> n;
    442 
    443     if (n <= 0) {
    444         cout << "Invalid list size!\n";
    445         return 0;
    446     }
    447 
    448     SearchList list(n);
    449     list.inputElements();
    450 
    451     while (true) {
    452         list.printMenu();
    453         cout << "Enter your choice: ";
    454         cin >> choice;
    455 
    456         switch (choice) {
    457             case 1: {
    458                 cout << "\nEnter element to search: ";
    459                 cin >> key;
    460                 int index = list.linearSearch(key);
    461                 if (index != -1)
    462                     cout << "\nElement " << key << " found at index " << index << ".\n";
    463                 else
    464                     cout << "\nElement " << key << " not found in the list.\n";
    465                 break;
    466             }
    467             case 2: {
    468                 cout << "\nEnter element to search: ";
    469                 cin >> key;
    470                 int index = list.binarySearch(key);
    471                 if (index != -1)
    472                     cout << "\nElement " << key << " found at index " << index << " in sorted array.\n";
    473                 else
    474                     cout << "\nElement " << key << " not found in the list.\n";
    475                 break;
    476             }
    477             case 0:
    478                 list.display();
    479                 break;
    480             case -1:
    481                 cout << "\nExiting program.....\nMemory cleared!\nExit 0\n";
    482                 return 0;
    483             default:
    484                 cout << "\nEntered wrong choice. Try again.\n";
    485         }
    486     }
    487 }
    488 ```
    489 
    490 ### Output:
    491 ![[Pasted image 20260922133534.png|400]]
    492 ![[Pasted image 20260922133550.png|402]]
    493 
    494 ### Discussion:
    495 This program demonstrates two fundamental searching techniques — **Linear Search** and **Binary Search** — wrapped inside a **SearchList** class that manages a dynamically allocated array of integers.
    496 
    497 Two private members support the class:
    498 
    499 - **arr** – a dynamically allocated integer pointer holding the list of elements.
    500 - **n** – the total number of elements in the list.
    501 
    502 A helper method, **insertionSort()**, is kept private since it is only meant to be used internally to prepare the array before a binary search is performed.
    503 
    504 The class exposes the following key methods:
    505 
    506 - **inputElements()** – Reads `n` integers from the user into the array.
    507 - **linearSearch()** – Iterates through the array sequentially, comparing each element with the key, and returns the index where a match is found, or `-1` if the key doesn't exist in the list.
    508 - **binarySearch()** – First sorts the array using **insertionSort()**, since binary search only works correctly on sorted data, then uses two pointers, **left** and **right**, to repeatedly narrow down the search range by comparing the key against the middle element until it is found or the range is exhausted.
    509 - **display()** – Prints all current elements of the list.
    510 - **printMenu()** – Uses a locally defined `MenuItem` struct (aliased as `menu`) to store menu options as `{id, name}` pairs, then loops through and prints them in a formatted two-column layout using `setw()`.
    511 
    512 The **main()** function drives the program using an infinite loop with a `switch` statement, allowing the user to repeatedly choose between performing a linear search, a binary search, displaying the list, or exiting the program. Since binary search requires sorted data, the program automatically sorts and displays the array before performing that operation, keeping the underlying array consistent for future operations.
    513 
    514 Finally, the destructor **~SearchList()** releases the dynamically allocated array using **delete[]** when the object is destroyed, avoiding memory leaks.
    515 
    516 ///
    517 ## Assignment 3
    518 ### Problem Statement:
    519 Write a program to sort a list of elements. Give the user the option to perform sorting using Insertion Sort, Bubble Sort, or Selection Sort.
    520 
    521 ### Problem Defination:
    522 Sorting is the process of arranging elements of a list in a particular order (ascending/descending).
    523 
    524 - **Insertion Sort:** Builds the sorted list one element at a time by picking an element and inserting it into its correct position among the already-sorted part. Time complexity `O(n²)`.
    525 - **Bubble Sort:** Repeatedly compares adjacent elements and swaps them if out of order, pushing the largest element to the end each pass. Time complexity `O(n²)`.
    526 - **Selection Sort:** Repeatedly finds the minimum element from the unsorted part and places it at the beginning. Time complexity `O(n²)`.
    527 
    528 ### Algorithm:
    529 **Insertion Sort:**
    530 ```
    531 procedure insertionSort(arr, n)
    532 begin
    533 	for i ← 1 to n - 1 do
    534 		key ← arr[i];
    535 		j ← i - 1;
    536 		while(j >= 0 and arr[j] > key) do
    537 			arr[j + 1] ← arr[j];
    538 			j ← j - 1;
    539 		end while
    540 		arr[j + 1] ← key;
    541 	end for
    542 end procedure
    543 ```
    544 
    545 **Bubble Sort:**
    546 ```
    547 procedure bubbleSort(arr, n)
    548 begin
    549 	for i ← 0 to n - 2 do
    550 		swapped ← false;
    551 		for j ← 0 to n - i - 2 do
    552 			if(arr[j] > arr[j + 1])
    553 				swap(arr[j], arr[j + 1]);
    554 				swapped ← true;
    555 			end if
    556 		end for
    557 		if(swapped = false)
    558 			break;
    559 		end if
    560 	end for
    561 end procedure
    562 ```
    563 
    564 **Selection Sort:**
    565 ```
    566 procedure selectionSort(arr, n)
    567 begin
    568 	for i ← 0 to n - 2 do
    569 		minIdx ← i;
    570 		for j ← i + 1 to n - 1 do
    571 			if(arr[j] < arr[minIdx])
    572 				minIdx ← j;
    573 			end if
    574 		end for
    575 		if(minIdx ≠ i)
    576 			swap(arr[i], arr[minIdx]);
    577 		end if
    578 	end for
    579 end procedure
    580 ```
    581 
    582 ### Source Code:
    583 ```
    584 #include <iostream>
    585 #include <iomanip>
    586 using namespace std;
    587 
    588 typedef struct MenuItem {
    589     int id;
    590     const char* name;
    591 } menu;
    592 
    593 class SortList {
    594 private:
    595     int *arr;
    596     int *tempArr;
    597     int n;
    598 
    599     void swapElements(int &a, int &b) {
    600         int temp = a;
    601         a = b;
    602         b = temp;
    603     }
    604 
    605     void reset() {
    606         for (int i = 0; i < n; i++) tempArr[i] = arr[i];
    607     }
    608 
    609 public:
    610     SortList(int size) {
    611         n = size;
    612         arr = new int[n];
    613         tempArr = new int[n];
    614     }
    615 
    616     void inputElements() {
    617         cout << "\nEnter " << n << " elements: ";
    618         for (int i = 0; i < n; i++) {
    619             cin >> arr[i];
    620             tempArr[i] = arr[i];
    621         }
    622     }
    623 
    624     void insertionSort() {
    625         reset();
    626         for (int i = 1; i < n; i++) {
    627             int key = tempArr[i];
    628             int j = i - 1;
    629             while (j >= 0 && tempArr[j] > key) {
    630                 tempArr[j + 1] = tempArr[j];
    631                 j--;
    632             }
    633             tempArr[j + 1] = key;
    634         }
    635         display();
    636     }
    637 
    638     void bubbleSort() {
    639         reset();
    640         for (int i = 0; i < n - 1; i++) {
    641             bool swapped = false;
    642             for (int j = 0; j < n - i - 1; j++) {
    643                 if (tempArr[j] > tempArr[j + 1]) {
    644                     swapElements(tempArr[j], tempArr[j + 1]);
    645                     swapped = true;
    646                 }
    647             }
    648             if (!swapped) break;
    649         }
    650         display();
    651     }
    652 
    653     void selectionSort() {
    654         reset();
    655         for (int i = 0; i < n - 1; i++) {
    656             int minIdx = i;
    657             for (int j = i + 1; j < n; j++) {
    658                 if (tempArr[j] < tempArr[minIdx]) minIdx = j;
    659             }
    660             if (minIdx != i) swapElements(tempArr[i], tempArr[minIdx]);
    661         }
    662         display();
    663     }
    664 
    665     void display() {
    666         cout << "Sorted Array: ";
    667         for (int i = 0; i < n; i++) cout << tempArr[i] << " ";
    668         cout << endl;
    669     }
    670 
    671     void displayOriginal() {
    672         cout << "\nOriginal List: ";
    673         for (int i = 0; i < n; i++) cout << arr[i] << " ";
    674         cout << endl;
    675     }
    676 
    677     void printMenu() {
    678         menu items[] = {
    679             {1, "Insertion Sort"}, {2, "Bubble Sort"},
    680             {3, "Selection Sort"}, {0, "Display Original"},
    681             {-1, "Exit"}
    682         };
    683         for (int i = 0; i < 5; i++) {
    684             cout << items[i].id << ". " << items[i].name << "\n";
    685         }
    686     }
    687 
    688     ~SortList() {
    689         delete[] arr;
    690         delete[] tempArr;
    691     }
    692 };
    693 
    694 int main() {
    695     int n, choice;
    696     cout << "Enter number of elements: ";
    697     cin >> n;
    698     if (n <= 0) {
    699         cout << "Invalid size!\n";
    700         return 0;
    701     }
    702 
    703     SortList sorter(n);
    704     sorter.inputElements();
    705 
    706     while (true) {
    707         sorter.printMenu();
    708         cout << "Enter your choice: ";
    709         cin >> choice;
    710 
    711         switch (choice) {
    712             case 1: sorter.insertionSort(); break;
    713             case 2: sorter.bubbleSort(); break;
    714             case 3: sorter.selectionSort(); break;
    715             case 0: sorter.displayOriginal(); break;
    716             case -1:
    717                 cout << "\nExiting program.....\nMemory cleared!\nExit 0\n";
    718                 return 0;
    719             default:
    720                 cout << "\nEntered wrong choice. Try again.\n";
    721         }
    722     }
    723 }
    724 ```
    725 
    726 ### Output:
    727 ![[Pasted image 20260922133021.png|522]]
    728 <p align="right">Continue to next page...</p>
    729 ///
    730 ![[Pasted image 20260922102559.png|521]]
    731 ### Discussion:
    732 - **insertionSort()** rebuilds the array from `arr` via `reset()`, then repeatedly takes an element (`key`) and shifts larger elements in the sorted left portion rightward until it finds the correct spot to insert the key.
    733 - **bubbleSort()** makes repeated passes, swapping adjacent out-of-order elements; a `swapped` flag lets it exit early once a pass makes no swaps, avoiding unnecessary iterations on an already-sorted array.
    734 - **selectionSort()** finds the index of the minimum element in the unsorted portion (`minIdx`) on each pass and swaps it into place at the front, growing the sorted portion by one each time.
    735 
    736 All three operate on `tempArr`, a working copy of the original `arr`, so the original input remains unaffected and can be displayed separately via `displayOriginal()`.
    737 
    738 ///
    739 ## Assignment 4
    740 ### Problem Statement:
    741 Implement a Singly Linked List. Include functions for insertion, deletion and search of a number, reverse the list, and concatenate two linked lists (include a function and also overload the `+` operator).
    742 
    743 ### Problem Defination:
    744 A **Linked List** is a linear data structure where elements (nodes) are connected using pointers, with each node storing data and a reference to the next node.
    745 
    746 - **Insertion/Deletion:** Adding or removing a node at the beginning, end, or a given position by adjusting pointer links.
    747 - **Search:** Traversing the list sequentially to find the position of a given value.
    748 - **Reverse:** Reversing the direction of the `next` pointers so the list traverses in the opposite order.
    749 - **Concatenation:** Joining two lists by linking the last node of the first list to the head of the second, done both via a function and an overloaded `+` operator.
    750 
    751 ### Algorithm:
    752 **Insertion at Beginning:**
    753 ```
    754 procedure insertAtBegin(head, val)
    755 begin
    756 	newNode ← create new node;
    757 	newNode.data ← val;
    758 	newNode.next ← head;
    759 	head ← newNode;
    760 end procedure
    761 ```
    762 
    763 **Insertion at End:**
    764 ```
    765 procedure insertAtEnd(head, val)
    766 begin
    767 	newNode ← create new node;
    768 	newNode.data ← val;
    769 	newNode.next ← NULL;
    770 	if(head = NULL)
    771 		head ← newNode;
    772 	else
    773 		temp ← head;
    774 		while(temp.next ≠ NULL) do
    775 			temp ← temp.next;
    776 		end while
    777 		temp.next ← newNode;
    778 	end if
    779 end procedure
    780 ```
    781 
    782 ///
    783 **Insertion at Position:**
    784 ```
    785 procedure insertAtPos(head, pos, val)
    786 begin
    787 	if(pos < 1)
    788 		print "Invalid Position";
    789 		return;
    790 	end if
    791 	if(pos = 1)
    792 		call insertAtBegin(head, val);
    793 		return;
    794 	end if
    795 	temp ← head;
    796 	for i ← 1 to pos - 2 do
    797 		if(temp = NULL)
    798 			break;
    799 		end if
    800 		temp ← temp.next;
    801 	end for
    802 	if(temp = NULL)
    803 		print "Out of range";
    804 		return;
    805 	end if
    806 	newNode ← create new node;
    807 	newNode.data ← val;
    808 	newNode.next ← temp.next;
    809 	temp.next ← newNode;
    810 end procedure
    811 ```
    812 
    813 **Deletion at Beginning:**
    814 ```
    815 procedure deleteAtBegin(head)
    816 begin
    817 	if(head = NULL)
    818 		print "List is empty";
    819 		return;
    820 	end if
    821 	temp ← head;
    822 	head ← head.next;
    823 	free temp;
    824 end procedure
    825 ```
    826 
    827 **Deletion at End:**
    828 ```
    829 procedure deleteAtEnd(head)
    830 begin
    831 	if(head = NULL)
    832 		print "List is empty";
    833 		return;
    834 	end if
    835 	if(head.next = NULL)
    836 		free head;
    837 		head ← NULL;
    838 		return;
    839 	end if
    840 	temp ← head;
    841 	while(temp.next.next ≠ NULL) do
    842 		temp ← temp.next;
    843 	end while
    844 	free temp.next;
    845 	temp.next ← NULL;
    846 end procedure
    847 ```
    848 
    849 **Deletion at Position:**
    850 ```
    851 procedure deleteAtPos(head, pos)
    852 begin
    853 	if(head = NULL or pos < 1)
    854 		print "Unable to process";
    855 		return;
    856 	end if
    857 	if(pos = 1)
    858 		call deleteAtBegin(head);
    859 		return;
    860 	end if
    861 	temp ← head;
    862 	for i ← 1 to pos - 2 do
    863 		if(temp = NULL)
    864 			break;
    865 		end if
    866 		temp ← temp.next;
    867 	end for
    868 	if(temp = NULL or temp.next = NULL)
    869 		print "Out of range";
    870 		return;
    871 	end if
    872 	delNode ← temp.next;
    873 	temp.next ← delNode.next;
    874 	free delNode;
    875 end procedure
    876 ```
    877 
    878 **Search:**
    879 ```
    880 procedure search(head, key)
    881 begin
    882 	temp ← head;
    883 	pos ← 1;
    884 	while(temp ≠ NULL) do
    885 		if(temp.data = key)
    886 			return pos;
    887 		end if
    888 		temp ← temp.next;
    889 		pos ← pos + 1;
    890 	end while
    891 	return -1;
    892 end procedure
    893 ```
    894 
    895 **Reverse:**
    896 ```
    897 procedure reverse(head)
    898 begin
    899 	prev ← NULL;
    900 	curr ← head;
    901 	nxt ← NULL;
    902 	while(curr ≠ NULL) do
    903 		nxt ← curr.next;
    904 		curr.next ← prev;
    905 		prev ← curr;
    906 		curr ← nxt;
    907 	end while
    908 	head ← prev;
    909 end procedure
    910 ```
    911 
    912 **Concatenate:**
    913 ```
    914 procedure concatenate(head1, head2)
    915 begin
    916 	if(head1 = NULL)
    917 		head1 ← head2;
    918 		head2 ← NULL;
    919 		return;
    920 	end if
    921 	temp ← head1;
    922 	while(temp.next ≠ NULL) do
    923 		temp ← temp.next;
    924 	end while
    925 	temp.next ← head2;
    926 	head2 ← NULL;
    927 end procedure
    928 ```
    929 
    930 ### Source Code:
    931 ```
    932 #include <iostream>
    933 using namespace std;
    934 
    935 typedef struct nodeType {
    936     int data;
    937     nodeType *next = nullptr;
    938 } node;
    939 
    940 class SinglyLinkedList {
    941 private:
    942     node *head;
    943 
    944 public:
    945     SinglyLinkedList() { head = nullptr; }
    946 
    947     SinglyLinkedList(const SinglyLinkedList &other) {
    948         head = nullptr;
    949         node *temp = other.head;
    950         while (temp != nullptr) {
    951             insertAtEnd(temp->data);
    952             temp = temp->next;
    953         }
    954     }
    955 
    956     void insertAtBegin(int val) {
    957         node *newNode = new node;
    958         newNode->data = val;
    959         newNode->next = head;
    960         head = newNode;
    961     }
    962 
    963     void insertAtEnd(int val) {
    964         node *newNode = new node;
    965         newNode->data = val;
    966         newNode->next = nullptr;
    967         if (head == nullptr) {
    968             head = newNode;
    969         } else {
    970             node *temp = head;
    971             while (temp->next != nullptr) temp = temp->next;
    972             temp->next = newNode;
    973         }
    974     }
    975 
    976     void insertAtPos(int pos, int val) {
    977         if (pos < 1) { cout << "Invalid Position!\n"; return; }
    978         if (pos == 1) { insertAtBegin(val); return; }
    979         node *temp = head;
    980         for (int i = 1; i < pos - 1 && temp != nullptr; i++) temp = temp->next;
    981         if (temp == nullptr) { cout << "Out of range!\n"; return; }
    982         node *newNode = new node;
    983         newNode->data = val;
    984         newNode->next = temp->next;
    985         temp->next = newNode;
    986     }
    987 
    988     void deleteAtBegin() {
    989         if (head == nullptr) { cout << "List is empty!\n"; return; }
    990         node *temp = head;
    991         head = head->next;
    992         delete temp;
    993     }
    994 
    995     void deleteAtEnd() {
    996         if (head == nullptr) { cout << "List is empty!\n"; return; }
    997         if (head->next == nullptr) { delete head; head = nullptr; return; }
    998         node *temp = head;
    999         while (temp->next->next != nullptr) temp = temp->next;
   1000         delete temp->next;
   1001         temp->next = nullptr;
   1002     }
   1003 
   1004     void deleteAtPos(int pos) {
   1005         if (head == nullptr || pos < 1) { cout << "Unable to process!\n"; return; }
   1006         if (pos == 1) { deleteAtBegin(); return; }
   1007         node *temp = head;
   1008         for (int i = 1; i < pos - 1 && temp != nullptr; i++) temp = temp->next;
   1009         if (temp == nullptr || temp->next == nullptr) { cout << "Out of range!\n"; return; }
   1010         node *delNode = temp->next;
   1011         temp->next = delNode->next;
   1012         delete delNode;
   1013     }
   1014 
   1015     int search(int key) {
   1016         node *temp = head;
   1017         int pos = 1;
   1018         while (temp != nullptr) {
   1019             if (temp->data == key) return pos;
   1020             temp = temp->next;
   1021             pos++;
   1022         }
   1023         return -1;
   1024     }
   1025 
   1026     void reverse() {
   1027         node *prev = nullptr, *curr = head, *nxt = nullptr;
   1028         while (curr != nullptr) {
   1029             nxt = curr->next;
   1030             curr->next = prev;
   1031             prev = curr;
   1032             curr = nxt;
   1033         }
   1034         head = prev;
   1035     }
   1036 
   1037     void concatenate(SinglyLinkedList &other) {
   1038         if (head == nullptr) { head = other.head; other.head = nullptr; return; }
   1039         node *temp = head;
   1040         while (temp->next != nullptr) temp = temp->next;
   1041         temp->next = other.head;
   1042         other.head = nullptr;
   1043     }
   1044 
   1045     SinglyLinkedList operator+(const SinglyLinkedList &other) const {
   1046         SinglyLinkedList result;
   1047         node *temp = head;
   1048         while (temp != nullptr) { result.insertAtEnd(temp->data); temp = temp->next; }
   1049         temp = other.head;
   1050         while (temp != nullptr) { result.insertAtEnd(temp->data); temp = temp->next; }
   1051         return result;
   1052     }
   1053 
   1054     void display() const {
   1055         node *temp = head;
   1056         cout << "List: ";
   1057         while (temp != nullptr) { cout << temp->data << " -> "; temp = temp->next; }
   1058         cout << "nullptr\n";
   1059     }
   1060 
   1061     void printMenu() {
   1062         cout << "1.insertAtBegin 2.insertAtEnd 3.insertAtPos 4.deleteAtBegin 5.deleteAtEnd \n"
   1063              << "6.deleteAtPos 7.search 8.reverse 9.concatenate 10.operator+ 0.Display -1.Exit\n";
   1064     }
   1065 
   1066     ~SinglyLinkedList() {
   1067         node *temp;
   1068         while (head != nullptr) { temp = head; head = head->next; delete temp; }
   1069     }
   1070 };
   1071 
   1072 int main() {
   1073     SinglyLinkedList list1;
   1074     int choice, val, pos;
   1075 
   1076     while (true) {
   1077         list1.printMenu();
   1078         cout << "Enter your choice: ";
   1079         cin >> choice;
   1080         switch (choice) {
   1081             case 1: cout << "Enter value: "; cin >> val; list1.insertAtBegin(val); break;
   1082             case 2: cout << "Enter value: "; cin >> val; list1.insertAtEnd(val); break;
   1083             case 3:
   1084                 cout << "Enter position: "; cin >> pos;
   1085                 cout << "Enter value: "; cin >> val;
   1086                 list1.insertAtPos(pos, val);
   1087                 break;
   1088             case 4: list1.deleteAtBegin(); break;
   1089             case 5: list1.deleteAtEnd(); break;
   1090             case 6: cout << "Enter position: "; cin >> pos; list1.deleteAtPos(pos); break;
   1091             case 7: {
   1092                 cout << "Enter value to search: "; cin >> val;
   1093                 int res = list1.search(val);
   1094                 if (res != -1) cout << "Found at position " << res << ".\n";
   1095                 else cout << "Not found.\n";
   1096                 break;
   1097             }
   1098             case 8: list1.reverse(); break;
   1099             case 9: {
   1100                 SinglyLinkedList list2;
   1101                 int m, tempVal;
   1102                 cout << "Enter number of elements in second list: "; cin >> m;
   1103                 for (int i = 0; i < m; i++) { cin >> tempVal; list2.insertAtEnd(tempVal); }
   1104                 list1.concatenate(list2);
   1105                 break;
   1106             }
   1107             case 10: {
   1108                 SinglyLinkedList list2;
   1109                 int m, tempVal;
   1110                 cout << "Enter number of elements in second list: "; cin >> m;
   1111                 for (int i = 0; i < m; i++) { cin >> tempVal; list2.insertAtEnd(tempVal); }
   1112                 SinglyLinkedList combined = list1 + list2;
   1113                 combined.display();
   1114                 break;
   1115             }
   1116             case 0: list1.display(); break;
   1117             case -1: cout << "Exiting...\n"; return 0;
   1118             default: cout << "Wrong choice. Try again.\n";
   1119         }
   1120     }
   1121 }
   1122 ```
   1123 
   1124 ### Output:
   1125 ![[Pasted image 20260922135426.png|564]]
   1126 <p align="right" >Continue to next page...</p>
   1127 ///
   1128 ![[Pasted image 20260922135454.png|561]]
   1129 ### Discussion:
   1130 - **insertAtBegin/insertAtEnd/insertAtPos** create a new node and link it into the chain — at the head, by traversing to the last node, or by traversing to the node just before the target position.
   1131 - **deleteAtBegin/deleteAtEnd/deleteAtPos** unlink a node by redirecting the previous node's `next` pointer around it before freeing it, with edge cases handled for an empty list or a single-node list.
   1132 - **search()** traverses the list sequentially, comparing each node's data with the key, returning its 1-based position or `-1`.
   1133 - **reverse()** rebuilds the list by walking through it once, flipping each node's `next` pointer to point backward using three tracking pointers (`prev`, `curr`, `nxt`).
   1134 - **concatenate()** links the last node of the calling list directly to the head of the other list, modifying the calling list in place.
   1135 - **operator+** builds an entirely new list by copying all nodes from both lists in sequence, leaving both original lists unmodified.
   1136 ///
   1137 ## Assignment 5
   1138 ### Problem Statement:
   1139 Implement a Doubly Linked List. Include functions for insertion, deletion and search of a number, and reverse the list.
   1140 
   1141 ### Problem Defination:
   1142 A **Doubly Linked List** is a linear data structure where each node stores data along with two pointers — `prev` and `next` — pointing to the previous and next nodes, allowing traversal in both directions.
   1143 
   1144 - **Insertion/Deletion:** Adding or removing a node at the beginning, end, or a given position by updating both `prev` and `next` links.
   1145 - **Search:** Traversing the list sequentially to find the position of a given value.
   1146 - **Reverse:** Swapping the `prev` and `next` pointers of every node so the list's direction is flipped.
   1147 
   1148 ### Algorithm:
   1149 **Insertion at Beginning:**
   1150 ```
   1151 procedure insAtBegin(head, val)
   1152 begin
   1153 	newNode ← create new node;
   1154 	newNode.data ← val;
   1155 	newNode.prev ← NULL;
   1156 	newNode.next ← head;
   1157 	if(head ≠ NULL)
   1158 		head.prev ← newNode;
   1159 	end if
   1160 	head ← newNode;
   1161 end procedure
   1162 ```
   1163 
   1164 **Insertion at End:**
   1165 ```
   1166 procedure insAtEnd(head, val)
   1167 begin
   1168 	newNode ← create new node;
   1169 	newNode.data ← val;
   1170 	newNode.next ← NULL;
   1171 	if(head = NULL)
   1172 		newNode.prev ← NULL;
   1173 		head ← newNode;
   1174 	else
   1175 		temp ← head;
   1176 		while(temp.next ≠ NULL) do
   1177 			temp ← temp.next;
   1178 		end while
   1179 		temp.next ← newNode;
   1180 		newNode.prev ← temp;
   1181 	end if
   1182 end procedure
   1183 ```
   1184 
   1185 **Insertion at Position:**
   1186 ```
   1187 procedure insAtPos(head, pos, val)
   1188 begin
   1189 	if(pos < 1)
   1190 		print "Invalid Position";
   1191 		return;
   1192 	end if
   1193 	if(pos = 1)
   1194 		call insAtBegin(head, val);
   1195 		return;
   1196 	end if
   1197 	temp ← head;
   1198 	for i ← 1 to pos - 2 do
   1199 		if(temp = NULL)
   1200 			break;
   1201 		end if
   1202 		temp ← temp.next;
   1203 	end for
   1204 	if(temp = NULL)
   1205 		print "Out of range";
   1206 		return;
   1207 	end if
   1208 	newNode ← create new node;
   1209 	newNode.data ← val;
   1210 	newNode.next ← temp.next;
   1211 	newNode.prev ← temp;
   1212 	if(temp.next ≠ NULL)
   1213 		temp.next.prev ← newNode;
   1214 	end if
   1215 	temp.next ← newNode;
   1216 end procedure
   1217 ```
   1218 
   1219 **Deletion at Beginning:**
   1220 ```
   1221 procedure delAtBegin(head)
   1222 begin
   1223 	if(head = NULL)
   1224 		print "List is empty";
   1225 		return;
   1226 	end if
   1227 	temp ← head;
   1228 	head ← head.next;
   1229 	if(head ≠ NULL)
   1230 		head.prev ← NULL;
   1231 	end if
   1232 	free temp;
   1233 end procedure
   1234 ```
   1235 
   1236 **Deletion at End:**
   1237 ```
   1238 procedure delAtEnd(head)
   1239 begin
   1240 	if(head = NULL)
   1241 		print "List is empty";
   1242 		return;
   1243 	end if
   1244 	if(head.next = NULL)
   1245 		free head;
   1246 		head ← NULL;
   1247 		return;
   1248 	end if
   1249 	temp ← head;
   1250 	while(temp.next ≠ NULL) do
   1251 		temp ← temp.next;
   1252 	end while
   1253 	temp.prev.next ← NULL;
   1254 	free temp;
   1255 end procedure
   1256 ```
   1257 
   1258 **Deletion at Position:**
   1259 ```
   1260 procedure delAtPos(head, pos)
   1261 begin
   1262 	if(head = NULL or pos < 1)
   1263 		print "Unable to process";
   1264 		return;
   1265 	end if
   1266 	if(pos = 1)
   1267 		call delAtBegin(head);
   1268 		return;
   1269 	end if
   1270 	temp ← head;
   1271 	for i ← 1 to pos - 1 do
   1272 		if(temp = NULL)
   1273 			break;
   1274 		end if
   1275 		temp ← temp.next;
   1276 	end for
   1277 	if(temp = NULL)
   1278 		print "Out of range";
   1279 		return;
   1280 	end if
   1281 	if(temp.next ≠ NULL)
   1282 		temp.next.prev ← temp.prev;
   1283 	end if
   1284 	if(temp.prev ≠ NULL)
   1285 		temp.prev.next ← temp.next;
   1286 	end if
   1287 	free temp;
   1288 end procedure
   1289 ```
   1290 
   1291 **Search:**
   1292 ```
   1293 procedure search(head, key)
   1294 begin
   1295 	if(head = NULL)
   1296 		print "List is empty";
   1297 		return;
   1298 	end if
   1299 	temp ← head;
   1300 	pos ← 1;
   1301 	while(temp ≠ NULL) do
   1302 		if(temp.data = key)
   1303 			print "Found at position: ", pos;
   1304 			return;
   1305 		end if
   1306 		temp ← temp.next;
   1307 		pos ← pos + 1;
   1308 	end while
   1309 	print "Element not found";
   1310 end procedure
   1311 ```
   1312 
   1313 **Reverse:**
   1314 ```
   1315 procedure reverse(head)
   1316 begin
   1317 	if(head = NULL or head.next = NULL)
   1318 		return;
   1319 	end if
   1320 	curr ← head;
   1321 	temp ← NULL;
   1322 	while(curr ≠ NULL) do
   1323 		temp ← curr.prev;
   1324 		curr.prev ← curr.next;
   1325 		curr.next ← temp;
   1326 		curr ← curr.prev;
   1327 	end while
   1328 	if(temp ≠ NULL)
   1329 		head ← temp.prev;
   1330 	end if
   1331 end procedure
   1332 ```
   1333 
   1334 ### Source Code:
   1335 ```
   1336 #include <iostream>
   1337 using namespace std;
   1338 
   1339 typedef struct nodeType {
   1340     int data;
   1341     nodeType *prev = nullptr;
   1342     nodeType *next = nullptr;
   1343 } node;
   1344 
   1345 class DoublyLinkedList {
   1346 private:
   1347     node *head;
   1348 
   1349 public:
   1350     DoublyLinkedList() { head = nullptr; }
   1351 
   1352     void insAtBegin() {
   1353         node *newNode = new node;
   1354         cout << "Enter the value: ";
   1355         cin >> newNode->data;
   1356         newNode->prev = nullptr;
   1357         newNode->next = head;
   1358         if (head != nullptr) head->prev = newNode;
   1359         head = newNode;
   1360     }
   1361 
   1362     void insAtEnd() {
   1363         node *newNode = new node;
   1364         cout << "Enter the value: ";
   1365         cin >> newNode->data;
   1366         newNode->next = nullptr;
   1367         if (head == nullptr) {
   1368             newNode->prev = nullptr;
   1369             head = newNode;
   1370         } else {
   1371             node *temp = head;
   1372             while (temp->next != nullptr) temp = temp->next;
   1373             temp->next = newNode;
   1374             newNode->prev = temp;
   1375         }
   1376     }
   1377 
   1378     void insAtPos() {
   1379         int pos;
   1380         cout << "Enter the position: ";
   1381         cin >> pos;
   1382         if (pos < 1) { cout << "Invalid Position!\n"; return; }
   1383         if (pos == 1) { insAtBegin(); return; }
   1384         node *temp = head;
   1385         for (int i = 1; i < pos - 1 && temp != nullptr; i++) temp = temp->next;
   1386         if (temp == nullptr) { cout << "Out of range!\n"; return; }
   1387         node *newNode = new node;
   1388         cout << "Enter the value: ";
   1389         cin >> newNode->data;
   1390         newNode->next = temp->next;
   1391         newNode->prev = temp;
   1392         if (temp->next != nullptr) temp->next->prev = newNode;
   1393         temp->next = newNode;
   1394     }
   1395 
   1396     void delAtBegin() {
   1397         if (head == nullptr) { cout << "List is empty!\n"; return; }
   1398         node *temp = head;
   1399         head = head->next;
   1400         if (head != nullptr) head->prev = nullptr;
   1401         delete temp;
   1402     }
   1403 
   1404     void delAtEnd() {
   1405         if (head == nullptr) { cout << "List is empty!\n"; return; }
   1406         if (head->next == nullptr) { delete head; head = nullptr; return; }
   1407         node *temp = head;
   1408         while (temp->next != nullptr) temp = temp->next;
   1409         temp->prev->next = nullptr;
   1410         delete temp;
   1411     }
   1412 
   1413     void delAtPos() {
   1414         if (head == nullptr) { cout << "List is empty!\n"; return; }
   1415         int pos;
   1416         cout << "Enter the position: ";
   1417         cin >> pos;
   1418         if (pos < 1) { cout << "Invalid Position!\n"; return; }
   1419         if (pos == 1) { delAtBegin(); return; }
   1420         node *temp = head;
   1421         for (int i = 1; i < pos && temp != nullptr; i++) temp = temp->next;
   1422         if (temp == nullptr) { cout << "Out of range!\n"; return; }
   1423         if (temp->next != nullptr) temp->next->prev = temp->prev;
   1424         if (temp->prev != nullptr) temp->prev->next = temp->next;
   1425         delete temp;
   1426     }
   1427 
   1428     void search() {
   1429         if (head == nullptr) { cout << "List is empty!\n"; return; }
   1430         int key, pos = 1;
   1431         cout << "Enter the element to search: ";
   1432         cin >> key;
   1433         node *temp = head;
   1434         while (temp != nullptr) {
   1435             if (temp->data == key) { cout << "Found at position: " << pos << "\n"; return; }
   1436             temp = temp->next;
   1437             pos++;
   1438         }
   1439         cout << "Element not found.\n";
   1440     }
   1441 
   1442     void reverse() {
   1443         if (head == nullptr || head->next == nullptr) return;
   1444         node *curr = head, *temp = nullptr;
   1445         while (curr != nullptr) {
   1446             temp = curr->prev;
   1447             curr->prev = curr->next;
   1448             curr->next = temp;
   1449             curr = curr->prev;
   1450         }
   1451         if (temp != nullptr) head = temp->prev;
   1452     }
   1453 
   1454     void display() {
   1455         node *temp = head;
   1456         cout << "List: nullptr  ";
   1457         while (temp != nullptr) { cout << temp->data << "  "; temp = temp->next; }
   1458         cout << "nullptr\n";
   1459     }
   1460 
   1461     void printMenu() {
   1462         cout << "1.insertAtBegin 2.insertAtEnd 3.insertAtPos 4.deleteAtBegin 5.deleteAtEnd \n"
   1463              << "6.deleteAtPos 7.search 8.reverse 0.Display -1.Exit\n";
   1464     }
   1465 
   1466     ~DoublyLinkedList() {
   1467         node *temp;
   1468         while (head != nullptr) { temp = head; head = head->next; delete temp; }
   1469     }
   1470 };
   1471 
   1472 int main() {
   1473     DoublyLinkedList list;
   1474     int choice;
   1475 
   1476     while (true) {
   1477         list.printMenu();
   1478         cout << "Enter your choice: ";
   1479         cin >> choice;
   1480 
   1481         switch (choice) {
   1482             case 1: list.insAtBegin(); break;
   1483             case 2: list.insAtEnd(); break;
   1484             case 3: list.insAtPos(); break;
   1485             case 4: list.delAtBegin(); break;
   1486             case 5: list.delAtEnd(); break;
   1487             case 6: list.delAtPos(); break;
   1488             case 7: list.search(); break;
   1489             case 8: list.reverse(); break;
   1490             case 0: list.display(); break;
   1491             case -1: cout << "Exiting...\n"; return 0;
   1492             default: cout << "Wrong choice. Try again.\n";
   1493         }
   1494     }
   1495 }
   1496 ```
   1497 
   1498 ///
   1499 ### Output:
   1500 ![[Pasted image 20260922142353.png|466]]
   1501 
   1502 ### Discussion:
   1503 - **insAtBegin/insAtEnd/insAtPos** create a new node and link it into the chain by updating both the `next` pointer of the preceding node and the `prev` pointer of the following node, unlike a singly linked list which only needs one direction updated.
   1504 - **delAtBegin/delAtEnd/delAtPos** unlink a node by connecting its neighboring nodes directly to each other via their `prev` and `next` pointers before freeing it, handling edge cases for an empty or single-node list.
   1505 - **search()** traverses the list sequentially from `head`, comparing each node's data with the key, and reports the 1-based position if found.
   1506 - **reverse()** walks through the entire list once, swapping each node's `prev` and `next` pointers, then updates `head` to what was previously the last node — reversing the traversal direction in place without allocating new nodes.
   1507 ///
   1508 ## Assignment 6
   1509 ### Problem Statement:
   1510 Implement a Circular Linked List. Include functions for insertion, deletion and search of a number, and reverse the list.
   1511 
   1512 ### Problem Defination:
   1513 A **Circular Linked List** is a linear structure where the last node's `next` points back to the head instead of `NULL`, forming a loop. Insertion/deletion require tracking the last node to preserve the loop; traversal loops must use `do-while`-style checks (`temp != head` after moving) to avoid infinite loops.
   1514 
   1515 ### Algorithm:
   1516 **Insertion at Beginning:**
   1517 ```
   1518 procedure insertAtBegin(head, val)
   1519 begin
   1520 	newNode ← create new node;
   1521 	newNode.data ← val;
   1522 	if(head = NULL)
   1523 		head ← newNode;
   1524 		newNode.next ← head;
   1525 	else
   1526 		temp ← head;
   1527 		while(temp.next ≠ head) do
   1528 			temp ← temp.next;
   1529 		end while
   1530 		newNode.next ← head;
   1531 		temp.next ← newNode;
   1532 		head ← newNode;
   1533 	end if
   1534 end procedure
   1535 ```
   1536 
   1537 **Insertion at End:**
   1538 ```
   1539 procedure insertAtEnd(head, val)
   1540 begin
   1541 	newNode ← create new node;
   1542 	newNode.data ← val;
   1543 	if(head = NULL)
   1544 		head ← newNode;
   1545 		newNode.next ← head;
   1546 	else
   1547 		temp ← head;
   1548 		while(temp.next ≠ head) do
   1549 			temp ← temp.next;
   1550 		end while
   1551 		temp.next ← newNode;
   1552 		newNode.next ← head;
   1553 	end if
   1554 end procedure
   1555 ```
   1556 
   1557 **Insertion at Position:**
   1558 ```
   1559 procedure insertAtPos(head, pos, val)
   1560 begin
   1561 	if(pos < 1)
   1562 		print "Invalid Position";
   1563 		return;
   1564 	end if
   1565 	if(pos = 1)
   1566 		call insertAtBegin(head, val);
   1567 		return;
   1568 	end if
   1569 	if(head = NULL)
   1570 		print "Out of range";
   1571 		return;
   1572 	end if
   1573 	temp ← head;
   1574 	for i ← 1 to pos - 2 do
   1575 		temp ← temp.next;
   1576 		if(temp = head)
   1577 			print "Out of range";
   1578 			return;
   1579 		end if
   1580 	end for
   1581 	newNode ← create new node;
   1582 	newNode.data ← val;
   1583 	newNode.next ← temp.next;
   1584 	temp.next ← newNode;
   1585 end procedure
   1586 ```
   1587 
   1588 **Deletion at Beginning:**
   1589 ```
   1590 procedure deleteAtBegin(head)
   1591 begin
   1592 	if(head = NULL)
   1593 		print "List is empty";
   1594 		return;
   1595 	end if
   1596 	if(head.next = head)
   1597 		free head;
   1598 		head ← NULL;
   1599 		return;
   1600 	end if
   1601 	temp ← head;
   1602 	last ← head;
   1603 	while(last.next ≠ head) do
   1604 		last ← last.next;
   1605 	end while
   1606 	head ← head.next;
   1607 	last.next ← head;
   1608 	free temp;
   1609 end procedure
   1610 ```
   1611 
   1612 **Deletion at End:**
   1613 ```
   1614 procedure deleteAtEnd(head)
   1615 begin
   1616 	if(head = NULL)
   1617 		print "List is empty";
   1618 		return;
   1619 	end if
   1620 	if(head.next = head)
   1621 		free head;
   1622 		head ← NULL;
   1623 		return;
   1624 	end if
   1625 	temp ← head;
   1626 	while(temp.next.next ≠ head) do
   1627 		temp ← temp.next;
   1628 	end while
   1629 	delNode ← temp.next;
   1630 	temp.next ← head;
   1631 	free delNode;
   1632 end procedure
   1633 ```
   1634 
   1635 **Deletion at Position:**
   1636 ```
   1637 procedure deleteAtPos(head, pos)
   1638 begin
   1639 	if(head = NULL or pos < 1)
   1640 		print "Unable to process";
   1641 		return;
   1642 	end if
   1643 	if(pos = 1)
   1644 		call deleteAtBegin(head);
   1645 		return;
   1646 	end if
   1647 	temp ← head;
   1648 	for i ← 1 to pos - 2 do
   1649 		temp ← temp.next;
   1650 		if(temp = head)
   1651 			print "Out of range";
   1652 			return;
   1653 		end if
   1654 	end for
   1655 	if(temp.next = head)
   1656 		print "Out of range";
   1657 		return;
   1658 	end if
   1659 	delNode ← temp.next;
   1660 	temp.next ← delNode.next;
   1661 	free delNode;
   1662 end procedure
   1663 ```
   1664 
   1665 **Search:**
   1666 ```
   1667 procedure search(head, key)
   1668 begin
   1669 	if(head = NULL)
   1670 		return -1;
   1671 	end if
   1672 	temp ← head;
   1673 	pos ← 1;
   1674 	repeat
   1675 		if(temp.data = key)
   1676 			return pos;
   1677 		end if
   1678 		temp ← temp.next;
   1679 		pos ← pos + 1;
   1680 	until temp = head;
   1681 	return -1;
   1682 end procedure
   1683 ```
   1684 
   1685 **Reverse:**
   1686 ```
   1687 procedure reverse(head)
   1688 begin
   1689 	if(head = NULL or head.next = head)
   1690 		return;
   1691 	end if
   1692 	prev ← NULL;
   1693 	curr ← head;
   1694 	nxt ← NULL;
   1695 	oldHead ← head;
   1696 	repeat
   1697 		nxt ← curr.next;
   1698 		curr.next ← prev;
   1699 		prev ← curr;
   1700 		curr ← nxt;
   1701 	until curr = head;
   1702 	oldHead.next ← prev;
   1703 	head ← prev;
   1704 end procedure
   1705 ```
   1706 ### Source Code:
   1707 ```
   1708 #include <iostream>
   1709 using namespace std;
   1710 
   1711 struct node {
   1712     int data;
   1713     node *next = nullptr;
   1714 };
   1715 
   1716 class CircularLinkedList {
   1717 private:
   1718     node *head = nullptr;
   1719 
   1720 public:
   1721     void insertAtBegin(int val) {
   1722         node *newNode = new node{val};
   1723         if (head == nullptr) { head = newNode; newNode->next = head; return; }
   1724         node *temp = head;
   1725         while (temp->next != head) temp = temp->next;
   1726         newNode->next = head;
   1727         temp->next = newNode;
   1728         head = newNode;
   1729     }
   1730 
   1731     void insertAtEnd(int val) {
   1732         node *newNode = new node{val};
   1733         if (head == nullptr) { head = newNode; newNode->next = head; return; }
   1734         node *temp = head;
   1735         while (temp->next != head) temp = temp->next;
   1736         temp->next = newNode;
   1737         newNode->next = head;
   1738     }
   1739 
   1740     void insertAtPos(int pos, int val) {
   1741         if (pos < 1) { cout << "Invalid Position!\n"; return; }
   1742         if (pos == 1) { insertAtBegin(val); return; }
   1743         if (head == nullptr) { cout << "Out of range!\n"; return; }
   1744         node *temp = head;
   1745         for (int i = 1; i < pos - 1; i++) {
   1746             temp = temp->next;
   1747             if (temp == head) { cout << "Out of range!\n"; return; }
   1748         }
   1749         node *newNode = new node{val};
   1750         newNode->next = temp->next;
   1751         temp->next = newNode;
   1752     }
   1753 
   1754     void deleteAtBegin() {
   1755         if (head == nullptr) { cout << "List is empty!\n"; return; }
   1756         if (head->next == head) { delete head; head = nullptr; return; }
   1757         node *temp = head, *last = head;
   1758         while (last->next != head) last = last->next;
   1759         head = head->next;
   1760         last->next = head;
   1761         delete temp;
   1762     }
   1763 
   1764     void deleteAtEnd() {
   1765         if (head == nullptr) { cout << "List is empty!\n"; return; }
   1766         if (head->next == head) { delete head; head = nullptr; return; }
   1767         node *temp = head;
   1768         while (temp->next->next != head) temp = temp->next;
   1769         node *delNode = temp->next;
   1770         temp->next = head;
   1771         delete delNode;
   1772     }
   1773 
   1774     void deleteAtPos(int pos) {
   1775         if (head == nullptr || pos < 1) { cout << "Unable to process!\n"; return; }
   1776         if (pos == 1) { deleteAtBegin(); return; }
   1777         node *temp = head;
   1778         for (int i = 1; i < pos - 1; i++) {
   1779             temp = temp->next;
   1780             if (temp == head) { cout << "Out of range!\n"; return; }
   1781         }
   1782         if (temp->next == head) { cout << "Out of range!\n"; return; }
   1783         node *delNode = temp->next;
   1784         temp->next = delNode->next;
   1785         delete delNode;
   1786     }
   1787 
   1788     int search(int key) {
   1789         if (head == nullptr) return -1;
   1790         node *temp = head;
   1791         int pos = 1;
   1792         do {
   1793             if (temp->data == key) return pos;
   1794             temp = temp->next;
   1795             pos++;
   1796         } while (temp != head);
   1797         return -1;
   1798     }
   1799 
   1800     void reverse() {
   1801         if (head == nullptr || head->next == head) return;
   1802         node *prev = nullptr, *curr = head, *nxt = nullptr, *oldHead = head;
   1803         do {
   1804             nxt = curr->next;
   1805             curr->next = prev;
   1806             prev = curr;
   1807             curr = nxt;
   1808         } while (curr != head);
   1809         oldHead->next = prev;
   1810         head = prev;
   1811     }
   1812 
   1813     void display() {
   1814         if (head == nullptr) { cout << "List is empty!\n"; return; }
   1815         node *temp = head;
   1816         cout << "List: ";
   1817         do { cout << temp->data << " -> "; temp = temp->next; } while (temp != head);
   1818         cout << "(head)\n";
   1819     }
   1820 
   1821     void printMenu() {
   1822         cout << "1.insertAtBegin 2.insertAtEnd 3.insertAtPos 4.deleteAtBegin 5.deleteAtEnd \n"
   1823              << "6.deleteAtPos 7.search 8.reverse 0.Display -1.Exit\n";
   1824     }
   1825 
   1826     ~CircularLinkedList() {
   1827         if (head == nullptr) return;
   1828         node *temp = head->next;
   1829         while (temp != head) { node *next = temp->next; delete temp; temp = next; }
   1830         delete head;
   1831     }
   1832 };
   1833 
   1834 int main() {
   1835     CircularLinkedList list;
   1836     int choice, val, pos;
   1837 
   1838     while (true) {
   1839         list.printMenu();
   1840         cout << "Enter your choice: ";
   1841         cin >> choice;
   1842 
   1843         switch (choice) {
   1844             case 1: cout << "Enter value: "; cin >> val; list.insertAtBegin(val); break;
   1845             case 2: cout << "Enter value: "; cin >> val; list.insertAtEnd(val); break;
   1846             case 3:
   1847                 cout << "Enter position: "; cin >> pos;
   1848                 cout << "Enter value: "; cin >> val;
   1849                 list.insertAtPos(pos, val);
   1850                 break;
   1851             case 4: list.deleteAtBegin(); break;
   1852             case 5: list.deleteAtEnd(); break;
   1853             case 6: cout << "Enter position: "; cin >> pos; list.deleteAtPos(pos); break;
   1854             case 7: {
   1855                 cout << "Enter value to search: "; cin >> val;
   1856                 int res = list.search(val);
   1857                 if (res != -1) cout << "Found at position " << res << ".\n";
   1858                 else cout << "Not found.\n";
   1859                 break;
   1860             }
   1861             case 8: list.reverse(); break;
   1862             case 0: list.display(); break;
   1863             case -1: cout << "Exiting...\n"; return 0;
   1864             default: cout << "Wrong choice. Try again.\n";
   1865         }
   1866     }
   1867 }
   1868 ```
   1869 
   1870 ///
   1871 ### Output:
   1872 ![[Pasted image 20260923185808.png]]
   1873 ![[Pasted image 20260923185824.png]]
   1874 ///
   1875 ### Discussion:
   1876 
   1877 - **insertAtBegin/insertAtEnd/insertAtPos** create a new node and link it in, always ensuring the last node's `next` still points to the (possibly updated) `head` to preserve the circle.
   1878 - **deleteAtBegin/deleteAtEnd/deleteAtPos** unlink a node by finding its neighbors and relinking around it, with the last node's `next` updated to the new head where relevant.
   1879 - **search()** traverses using a `do-while` loop (since `head` itself must be checked first) and stops once it loops back to `head`.
   1880 - **reverse()** performs a standard 3-pointer reversal (`prev`, `curr`, `nxt`) but loops until `curr` returns to the original `head`, then fixes the old head's `next` to close the circle with the new head.
   1881 
   1882 ///
   1883 ## Assignment 7
   1884 ### Problem Statement:
   1885 Perform Stack operations using Linked List implementation.
   1886 ### Problem Defination:
   1887 A **Stack** is a linear data structure that follows LIFO (Last In First Out) order. In a linked list implementation, each element is stored as a **node** containing data and a pointer to the next node, with the **top** pointer always referring to the most recently inserted node.
   1888 
   1889 - **Push:** Insert a new node at the top.
   1890 - **Pop:** Remove the node from the top.
   1891 - **Peek:** View the top element without removing it.
   1892 ### Algorithm:
   1893 **Check Empty:**
   1894 ```
   1895 procedure isEmpty(top)
   1896 begin
   1897 	if(top = NULL)
   1898 		return true;
   1899 	else
   1900 		return false;
   1901 	end if
   1902 end procedure
   1903 ```
   1904 
   1905 **Push Operation:**
   1906 ```
   1907 procedure push(top, val)
   1908 begin
   1909 	newNode ← create new node;
   1910 	newNode.data ← val;
   1911 	newNode.next ← top;
   1912 	top ← newNode;
   1913 end procedure
   1914 ```
   1915 
   1916 **Pop Operation:**
   1917 ```
   1918 procedure pop(top)
   1919 begin
   1920 	if(isEmpty(top))
   1921 		print "Stack Underflow";
   1922 		return;
   1923 	end if
   1924 	temp ← top;
   1925 	val ← temp.data;
   1926 	top ← top.next;
   1927 	free temp;
   1928 	return val;
   1929 end procedure
   1930 ```
   1931   
   1932 **Peek Operation:**
   1933 ```
   1934 procedure peek(top)
   1935 begin
   1936 	if(isEmpty(top))
   1937 		print "Stack is empty";
   1938 		return;
   1939 	end if
   1940 	return top.data;
   1941 end procedure
   1942 ```
   1943   
   1944 ### Source Code:
   1945 ```
   1946 #include <iostream>
   1947 using namespace std;
   1948 
   1949 struct node
   1950 {
   1951     int data;
   1952     node *next;
   1953 };
   1954 
   1955 class Stack
   1956 {
   1957 private:
   1958     node *top;
   1959 
   1960 public:
   1961     Stack() { top = nullptr; }
   1962 
   1963     bool isEmpty() { return (top == nullptr); }
   1964 
   1965     void push(int val)
   1966     {
   1967         node *newNode = new node;
   1968         newNode->data = val;
   1969         newNode->next = top;
   1970         top = newNode;
   1971     }
   1972 
   1973     int pop()
   1974     {
   1975         if (isEmpty())
   1976         {
   1977             cout << "Stack Underflow!\n";
   1978             return -1;
   1979         }
   1980         node *temp = top;
   1981         int val = temp->data;
   1982         top = top->next;
   1983         delete temp;
   1984         return val;
   1985     }
   1986 
   1987     int peek()
   1988     {
   1989         if (isEmpty())
   1990         {
   1991             cout << "Stack is empty!\n";
   1992             return -1;
   1993         }
   1994         return top->data;
   1995     }
   1996 
   1997     void display()
   1998     {
   1999         if (isEmpty())
   2000         {
   2001             cout << "Stack is empty!\n";
   2002             return;
   2003         }
   2004         node *temp = top;
   2005         while (temp != nullptr)
   2006         {
   2007             cout << temp->data << " ";
   2008             temp = temp->next;
   2009         }
   2010         cout << endl;
   2011     }
   2012 
   2013     ~Stack()
   2014     {
   2015         node *temp;
   2016         while (top != nullptr)
   2017         {
   2018             temp = top;
   2019             top = top->next;
   2020             delete temp;
   2021         }
   2022     }
   2023 };
   2024 
   2025 int main()
   2026 {
   2027     Stack s;
   2028     int choice, val;
   2029 
   2030     while (true)
   2031     {
   2032         cout << "1.push 2.pop 3.peek 4.isEmpty 0.Display -1.Exit\n";
   2033         cout << "Enter your choice: ";
   2034         cin >> choice;
   2035 
   2036         switch (choice)
   2037         {
   2038         case 1:
   2039             cout << "Enter value: ";
   2040             cin >> val;
   2041             s.push(val);
   2042             break;
   2043 
   2044         case 2:
   2045         {
   2046             int v = s.pop();
   2047             if (v != -1)
   2048                 cout << "Popped value: " << v << endl;
   2049             break;
   2050         }
   2051 
   2052         case 3:
   2053         {
   2054             int v = s.peek();
   2055             if (v != -1)
   2056                 cout << "Top element: " << v << endl;
   2057             break;
   2058         }
   2059 
   2060         case 4:
   2061             cout << (s.isEmpty() ? "Empty\n" : "Not empty\n");
   2062             break;
   2063 
   2064         case 0:
   2065             s.display();
   2066             break;
   2067 
   2068         case -1:
   2069             cout << "Exiting...\n";
   2070             return 0;
   2071 
   2072         default:
   2073             cout << "Wrong choice.\n";
   2074         }
   2075     }
   2076 }
   2077 ```
   2078 
   2079 ### Output:  
   2080 ![[Pasted image 20260923191234.png]]
   2081 
   2082 ### Discussion:
   2083 - **push()** creates a new node, links it to the current top, and updates `top` to point to this new node.
   2084 - **pop()** checks for underflow, then removes the node pointed to by `top`, updates `top` to the next node, and returns the removed value.
   2085 - **peek()** returns the data stored at `top` without modifying the stack.
   2086 
   2087 ///
   2088 ## Assignment 8
   2089 ### Problem Statement:
   2090 Perform Stack operations using Array implementation.
   2091 ### Problem Defination:
   2092 A **Stack** is a linear data structure that follows LIFO (Last In First Out) order. Elements are added and removed only from one end, called the **top**.
   2093 - **Push:** Insert an element at the top.
   2094 - **Pop:** Remove the element from the top.
   2095 - **Peek:** View the top element without removing it.
   2096 ### Algorithm:
   2097 **Check Full:**
   2098 ```
   2099 procedure isFull(top, capacity)
   2100 begin
   2101 	if(top = capacity - 1)
   2102 		return true;
   2103 	else
   2104 		return false;
   2105 	end if
   2106 end procedure
   2107 ```
   2108 
   2109 **Check Empty:**
   2110 ```
   2111 procedure isEmpty(top)
   2112 begin
   2113 	if(top = -1)
   2114 		return true;
   2115 	else
   2116 		return false;
   2117 	end if
   2118 end procedure
   2119 ```
   2120 
   2121 **Push Operation:**
   2122 ```
   2123 procedure push(arr, top, capacity, val)
   2124 begin
   2125 	if(isFull(top, capacity))
   2126 		print "Stack Overflow";
   2127 		return;
   2128 	end if
   2129 	top ← top + 1;
   2130 	arr[top] ← val;
   2131 end procedure
   2132 ```
   2133 
   2134 **Pop Operation:**
   2135 ```
   2136 procedure pop(arr, top)
   2137 begin
   2138 	if(isEmpty(top))
   2139 		print "Stack Underflow";
   2140 		return;
   2141 	end if
   2142 	val ← arr[top];
   2143 	top ← top - 1;
   2144 	return val;
   2145 end procedure
   2146 ```
   2147 
   2148 **Peek Operation:**
   2149 ```
   2150 procedure peek(arr, top)
   2151 begin
   2152 	if(isEmpty(top))
   2153 		print "Stack is empty";
   2154 		return;
   2155 	end if
   2156 	return arr[top];
   2157 end procedure
   2158 ```
   2159 
   2160 ### Source Code:
   2161 ```
   2162 #include <iostream>
   2163 using namespace std;
   2164 
   2165 class Stack {
   2166 private:
   2167     int *arr;
   2168     int top;
   2169     int capacity;
   2170 
   2171 public:
   2172     Stack(int size) {
   2173         capacity = size;
   2174         arr = new int[capacity];
   2175         top = -1;
   2176     }
   2177 
   2178     bool isFull() { return (top == capacity - 1); }
   2179     bool isEmpty() { return (top == -1); }
   2180 
   2181     void push() {
   2182         if (isFull()) { cout << "Stack Overflow!\n"; return; }
   2183         int val;
   2184         cout << "Enter the value: ";
   2185         cin >> val;
   2186         arr[++top] = val;
   2187     }
   2188 
   2189     void pop() {
   2190         if (isEmpty()) { cout << "Stack Underflow!\n"; return; }
   2191         int val = arr[top--];
   2192         cout << "Popped value: " << val << endl;
   2193     }
   2194 
   2195     void peek() {
   2196         if (isEmpty()) { cout << "Stack is empty!\n"; return; }
   2197         cout << "Top element: " << arr[top] << endl;
   2198     }
   2199 
   2200     void display() {
   2201         if (isEmpty()) { cout << "Stack is empty!\n"; return; }
   2202         for (int i = top; i >= 0; i--) cout << arr[i] << " ";
   2203         cout << endl;
   2204     }
   2205 
   2206     ~Stack() { delete[] arr; }
   2207 };
   2208 
   2209 int main() {
   2210     int size, choice;
   2211     cout << "Enter stack capacity: ";
   2212     cin >> size;
   2213     if (size <= 0) { cout << "Invalid size!\n"; return 0; }
   2214 
   2215     Stack s(size);
   2216     while (true) {
   2217         cout << "1.push 2.pop 3.peek 4.isFull 5.isEmpty 0.Display -1.Exit\n";
   2218         cout << "Enter your choice: ";
   2219         cin >> choice;
   2220 
   2221         switch (choice) {
   2222             case 1: s.push(); break;
   2223             case 2: s.pop(); break;
   2224             case 3: s.peek(); break;
   2225             case 4: cout << (s.isFull() ? "Full\n" : "Not full\n"); break;
   2226             case 5: cout << (s.isEmpty() ? "Empty\n" : "Not empty\n"); break;
   2227             case 0: s.display(); break;
   2228             case -1: cout << "Exiting...\n"; return 0;
   2229             default: cout << "Wrong choice.\n";
   2230         }
   2231     }
   2232 }
   2233 ```
   2234 
   2235 ### Output:
   2236 ![[Pasted image 20260923191813.png]]
   2237 
   2238 ### Discussion:
   2239 - **push()** checks for overflow, then increments `top` and stores the value at `arr[top]`.
   2240 - **pop()** checks for underflow, then returns `arr[top]` and decrements `top`, effectively removing it logically without clearing memory.
   2241 - **peek()** returns `arr[top]` without modifying `top`, allowing the caller to inspect the top element.
   2242 
   2243 ///
   2244 ## Assignment 9
   2245 ### Problem Statement:
   2246 Perform Queue operations using Array.
   2247 ### Problem Defination:
   2248 A **Queue** is a linear data structure that follows FIFO (First In First Out) order. Elements are inserted from the **rear** and removed from the **front**.
   2249 - **Enqueue:** Insert an element at the rear.
   2250 - **Dequeue:** Remove an element from the front.
   2251 - **Peek:** View the front element without removing it.
   2252 ### Algorithm:
   2253 **Check Full:**
   2254 ```
   2255 procedure isFull(rear, capacity)
   2256 begin
   2257 	if(rear = capacity - 1)
   2258 		return true;
   2259 	else
   2260 		return false;
   2261 	end if
   2262 end procedure
   2263 ```
   2264 
   2265 **Check Empty:**
   2266 ```
   2267 procedure isEmpty(front, rear)
   2268 begin
   2269 	if(front = -1 or front > rear)
   2270 		return true;
   2271 	else
   2272 		return false;
   2273 	end if
   2274 end procedure
   2275 ```
   2276 
   2277 **Enqueue Operation:**
   2278 ```
   2279 procedure enqueue(arr, front, rear, capacity, val)
   2280 begin
   2281 	if(isFull(rear, capacity))
   2282 		print "Queue Overflow";
   2283 		return;
   2284 	end if
   2285 	if(front = -1)
   2286 		front ← 0;
   2287 	end if
   2288 	rear ← rear + 1;
   2289 	arr[rear] ← val;
   2290 end procedure
   2291 ```
   2292 
   2293 **Dequeue Operation:**
   2294 ```
   2295 procedure dequeue(arr, front, rear)
   2296 begin
   2297 	if(isEmpty(front, rear))
   2298 		print "Queue Underflow";
   2299 		return;
   2300 	end if
   2301 	val ← arr[front];
   2302 	front ← front + 1;
   2303 	if(front > rear)
   2304 		front ← -1;
   2305 		rear ← -1;
   2306 	end if
   2307 	return val;
   2308 end procedure
   2309 ```
   2310 
   2311 **Peek Operation:**
   2312 ```
   2313 procedure peek(arr, front, rear)
   2314 begin
   2315 	if(isEmpty(front, rear))
   2316 		print "Queue is empty";
   2317 		return;
   2318 	end if
   2319 	return arr[front];
   2320 end procedure
   2321 ```
   2322 
   2323 ### Source Code:
   2324 ```
   2325 #include <iostream>
   2326 using namespace std;
   2327 
   2328 class Queue {
   2329 private:
   2330     int *arr;
   2331     int front, rear, capacity;
   2332 
   2333 public:
   2334     Queue(int size) {
   2335         capacity = size;
   2336         arr = new int[capacity];
   2337         front = -1;
   2338         rear = -1;
   2339     }
   2340 
   2341     bool isFull() { return (rear == capacity - 1); }
   2342     bool isEmpty() { return (front == -1 || front > rear); }
   2343 
   2344     void enqueue() {
   2345         if (isFull()) { cout << "Queue Overflow!\n"; return; }
   2346         int val;
   2347         cout << "Enter the value: ";
   2348         cin >> val;
   2349         if (front == -1) front = 0;
   2350         arr[++rear] = val;
   2351     }
   2352 
   2353     void dequeue() {
   2354         if (isEmpty()) { cout << "Queue Underflow!\n"; return; }
   2355         int val = arr[front++];
   2356         if (front > rear) { front = -1; rear = -1; }
   2357         cout << "Dequeued value: " << val << endl;
   2358     }
   2359 
   2360     void peek() {
   2361         if (isEmpty()) { cout << "Queue is empty!\n"; return; }
   2362         cout << "Front element: " << arr[front] << endl;
   2363     }
   2364 
   2365     void display() {
   2366         if (isEmpty()) { cout << "Queue is empty!\n"; return; }
   2367         for (int i = front; i <= rear; i++) cout << arr[i] << " ";
   2368         cout << endl;
   2369     }
   2370 
   2371     ~Queue() { delete[] arr; }
   2372 };
   2373 
   2374 int main() {
   2375     int size, choice;
   2376     cout << "Enter queue capacity: ";
   2377     cin >> size;
   2378     if (size <= 0) { cout << "Invalid size!\n"; return 0; }
   2379 
   2380     Queue q(size);
   2381     while (true) {
   2382         cout << "1.enqueue 2.dequeue 3.peek 4.isFull 5.isEmpty 0.Display -1.Exit\n";
   2383         cout << "Enter your choice: ";
   2384         cin >> choice;
   2385 
   2386         switch (choice) {
   2387             case 1: q.enqueue(); break;
   2388             case 2: q.dequeue(); break;
   2389             case 3: q.peek(); break;
   2390             case 4: cout << (q.isFull() ? "Full\n" : "Not full\n"); break;
   2391             case 5: cout << (q.isEmpty() ? "Empty\n" : "Not empty\n"); break;
   2392             case 0: q.display(); break;
   2393             case -1: cout << "Exiting...\n"; return 0;
   2394             default: cout << "Wrong choice.\n";
   2395         }
   2396     }
   2397 }
   2398 ```
   2399 
   2400 ### Output:
   2401 ![[Pasted image 20260923192135.png|476]]
   2402 
   2403 ///
   2404 ### Discussion:
   2405 - **enqueue()** checks for overflow, initializes `front` to 0 on the first insertion, then places the value at `arr[++rear]`.
   2406 - **dequeue()** checks for underflow, returns `arr[front]`, increments `front`, and resets both `front` and `rear` to `-1` once the queue empties — since this linear queue does not reuse freed front slots.
   2407 - **peek()** returns `arr[front]` without modifying either pointer.
   2408 
   2409 ///
   2410 ## Assignment 10
   2411 ### Problem Statement:
   2412 Perform Circular Queue operations using Array.
   2413 ### Problem Defination:
   2414 A **Circular Queue** is a queue implemented using a fixed-size array where the rear wraps around to the front once it reaches the end, using modulo arithmetic. This allows reuse of freed slots, unlike a linear queue.
   2415 ### Algorithm:
   2416 **Check Empty:**
   2417 ```
   2418 procedure isEmpty(front)
   2419 begin
   2420 	if(front = -1)
   2421 		return true;
   2422 	else
   2423 		return false;
   2424 	end if
   2425 end procedure
   2426 ```
   2427 
   2428 **Check Full:**
   2429 ```
   2430 procedure isFull(front, rear, size)
   2431 begin
   2432 	if((rear + 1) mod size = front)
   2433 		return true;
   2434 	else
   2435 		return false;
   2436 	end if
   2437 end procedure
   2438 ```
   2439 
   2440 **Enqueue Operation:**
   2441 ```
   2442 procedure enqueue(queue, front, rear, size, val)
   2443 begin
   2444 	if(isFull(front, rear, size))
   2445 		print "Queue is Full";
   2446 		return;
   2447 	end if
   2448 	if(isEmpty(front))
   2449 		front ← 0;
   2450 		rear ← 0;
   2451 	else
   2452 		rear ← (rear + 1) mod size;
   2453 	end if
   2454 	queue[rear] ← val;
   2455 end procedure
   2456 ```
   2457 
   2458 **Dequeue Operation:**
   2459 ```
   2460 procedure dequeue(queue, front, rear, size)
   2461 begin
   2462 	if(isEmpty(front))
   2463 		print "Queue is Empty";
   2464 		return;
   2465 	end if
   2466 	val ← queue[front];
   2467 	if(front = rear)
   2468 		front ← -1;
   2469 		rear ← -1;
   2470 	else
   2471 		front ← (front + 1) mod size;
   2472 	end if
   2473 	return val;
   2474 end procedure
   2475 ```
   2476 
   2477 **Peek Operation:**
   2478 ```
   2479 procedure peek(queue, front)
   2480 begin
   2481 	if(isEmpty(front))
   2482 		print "Queue is Empty";
   2483 		return;
   2484 	end if
   2485 	return queue[front];
   2486 end procedure
   2487 ```
   2488 
   2489 ### Source Code:
   2490 ```
   2491 #include <iostream>
   2492 using namespace std;
   2493 
   2494 class CircularQueue {
   2495 private:
   2496     int *queue;
   2497     int front, rear, size;
   2498 
   2499 public:
   2500     CircularQueue(int n) {
   2501         size = n;
   2502         queue = new int[size];
   2503         front = -1;
   2504         rear = -1;
   2505     }
   2506 
   2507     bool isEmpty() { return front == -1; }
   2508     bool isFull() { return (rear + 1) % size == front; }
   2509 
   2510     void enqueue(int val) {
   2511         if (isFull()) { cout << "Queue is Full!\n"; return; }
   2512         if (isEmpty()) { front = 0; rear = 0; }
   2513         else rear = (rear + 1) % size;
   2514         queue[rear] = val;
   2515     }
   2516 
   2517     void dequeue() {
   2518         if (isEmpty()) { cout << "Queue is Empty!\n"; return; }
   2519         int val = queue[front];
   2520         if (front == rear) { front = -1; rear = -1; }
   2521         else front = (front + 1) % size;
   2522         cout << "Removed: " << val << endl;
   2523     }
   2524 
   2525     void peek() {
   2526         if (isEmpty()) { cout << "Queue is Empty!\n"; return; }
   2527         cout << "Front element: " << queue[front] << endl;
   2528     }
   2529 
   2530     void display() {
   2531         if (isEmpty()) { cout << "Queue is Empty!\n"; return; }
   2532         int i = front;
   2533         while (true) {
   2534             cout << queue[i] << " ";
   2535             if (i == rear) break;
   2536             i = (i + 1) % size;
   2537         }
   2538         cout << endl;
   2539     }
   2540 
   2541     ~CircularQueue() { delete[] queue; }
   2542 };
   2543 
   2544 int main() {
   2545     int n, choice, val;
   2546     cout << "Enter queue size: ";
   2547     cin >> n;
   2548     if (n <= 0) { cout << "Invalid size!\n"; return 0; }
   2549 
   2550     CircularQueue q(n);
   2551     while (true) {
   2552         cout << "1.enqueue 2.dequeue 3.peek 4.isEmpty 5.isFull 6.Display 0.Exit\n";
   2553         cout << "Enter your choice: ";
   2554         cin >> choice;
   2555 
   2556         switch (choice) {
   2557             case 1: cout << "Enter value: "; cin >> val; q.enqueue(val); break;
   2558             case 2: q.dequeue(); break;
   2559             case 3: q.peek(); break;
   2560             case 4: cout << (q.isEmpty() ? "Empty\n" : "Not empty\n"); break;
   2561             case 5: cout << (q.isFull() ? "Full\n" : "Not full\n"); break;
   2562             case 6: q.display(); break;
   2563             case 0: cout << "Exiting...\n"; return 0;
   2564             default: cout << "Wrong choice.\n";
   2565         }
   2566     }
   2567 }
   2568 ```
   2569 
   2570 ### Output:
   2571 ![[Pasted image 20260923192435.png|483]]
   2572 ///
   2573 ### Discussion:
   2574 - **enqueue()** checks fullness using `(rear + 1) % size == front`, sets `front`/`rear` to `0` on the first insertion, otherwise advances `rear` circularly with modulo before storing the value.
   2575 - **dequeue()** returns `queue[front]`, and either resets both pointers to `-1` (if it was the last element) or advances `front` circularly, allowing wrapped-around slots to be reused.
   2576 - **peek()** simply returns `queue[front]` without altering any pointer.
   2577 
   2578 ///
   2579 ## Assignment 11
   2580 ### Problem Statement:
   2581 Perform Queue operations using Linked List.
   2582 ### Problem Defination:
   2583 A **Queue** implemented via a linked list uses two pointers, `front` and `rear`, to track the first and last nodes, allowing enqueue and dequeue in `O(1)` without a fixed capacity.
   2584 ### Algorithm:
   2585 **Check Empty:**
   2586 ```
   2587 procedure isEmpty(front)
   2588 begin
   2589 	if(front = NULL)
   2590 		return true;
   2591 	else
   2592 		return false;
   2593 	end if
   2594 end procedure
   2595 ```
   2596 
   2597 **Enqueue Operation:**
   2598 ```
   2599 procedure enqueue(front, rear, val)
   2600 begin
   2601 	newNode ← create new node;
   2602 	newNode.data ← val;
   2603 	newNode.next ← NULL;
   2604 	if(isEmpty(front))
   2605 		front ← newNode;
   2606 		rear ← newNode;
   2607 	else
   2608 		rear.next ← newNode;
   2609 		rear ← newNode;
   2610 	end if
   2611 end procedure
   2612 ```
   2613 
   2614 **Dequeue Operation:**
   2615 ```
   2616 procedure dequeue(front, rear)
   2617 begin
   2618 	if(isEmpty(front))
   2619 		print "Queue Underflow";
   2620 		return;
   2621 	end if
   2622 	temp ← front;
   2623 	val ← temp.data;
   2624 	front ← front.next;
   2625 	if(front = NULL)
   2626 		rear ← NULL;
   2627 	end if
   2628 	free temp;
   2629 	return val;
   2630 end procedure
   2631 ```
   2632 
   2633 **Peek Operation:**
   2634 ```
   2635 procedure peek(front)
   2636 begin
   2637 	if(isEmpty(front))
   2638 		print "Queue is empty";
   2639 		return;
   2640 	end if
   2641 	return front.data;
   2642 end procedure
   2643 ```
   2644 
   2645 ### Source Code:
   2646 ```
   2647 #include <iostream>
   2648 using namespace std;
   2649 
   2650 struct node {
   2651     int data;
   2652     node *next = nullptr;
   2653 };
   2654 
   2655 class Queue {
   2656 private:
   2657     node *front, *rear;
   2658 
   2659 public:
   2660     Queue() { front = nullptr; rear = nullptr; }
   2661     bool isEmpty() { return (front == nullptr); }
   2662 
   2663     void enqueue() {
   2664         node *newNode = new node;
   2665         cout << "Enter the value: ";
   2666         cin >> newNode->data;
   2667         newNode->next = nullptr;
   2668         if (isEmpty()) front = rear = newNode;
   2669         else { rear->next = newNode; rear = newNode; }
   2670     }
   2671 
   2672     void dequeue() {
   2673         if (isEmpty()) { cout << "Queue Underflow!\n"; return; }
   2674         node *temp = front;
   2675         int val = temp->data;
   2676         front = front->next;
   2677         if (front == nullptr) rear = nullptr;
   2678         delete temp;
   2679         cout << "Dequeued: " << val << endl;
   2680     }
   2681 
   2682     void peek() {
   2683         if (isEmpty()) { cout << "Queue is empty!\n"; return; }
   2684         cout << "Front element: " << front->data << endl;
   2685     }
   2686 
   2687     void display() {
   2688         if (isEmpty()) { cout << "Queue is empty!\n"; return; }
   2689         node *temp = front;
   2690         while (temp != nullptr) { cout << temp->data << " "; temp = temp->next; }
   2691         cout << endl;
   2692     }
   2693 
   2694     ~Queue() {
   2695         node *temp;
   2696         while (front != nullptr) { temp = front; front = front->next; delete temp; }
   2697     }
   2698 };
   2699 
   2700 int main() {
   2701     Queue q;
   2702     int choice;
   2703 
   2704     while (true) {
   2705         cout << "1.enqueue 2.dequeue 3.peek 4.isEmpty 0.Display -1.Exit\n";
   2706         cout << "Enter your choice: ";
   2707         cin >> choice;
   2708 
   2709         switch (choice) {
   2710             case 1: q.enqueue(); break;
   2711             case 2: q.dequeue(); break;
   2712             case 3: q.peek(); break;
   2713             case 4: cout << (q.isEmpty() ? "Empty\n" : "Not empty\n"); break;
   2714             case 0: q.display(); break;
   2715             case -1: cout << "Exiting...\n"; return 0;
   2716             default: cout << "Wrong choice.\n";
   2717         }
   2718     }
   2719 }
   2720 ```
   2721 
   2722 ### Output:
   2723 ![[Pasted image 20260923192749.png]]
   2724 
   2725 ### Discussion:
   2726 - **enqueue()** creates a new node and links it after `rear`, updating `rear` to point to it; if the queue was empty, both `front` and `rear` are set to the new node.
   2727 - **dequeue()** removes the node at `front`, advancing `front` to the next node, and resets `rear` to `NULL` if the list becomes empty.
   2728 - **peek()** returns `front->data` without modifying the queue.
   2729 
   2730 ///
   2731 ## Assignment 12
   2732 ### Problem Statement:
   2733 Create and perform different operations on Double-ended Queues (Deque) using Linked List implementation.
   2734 ### Problem Defination:
   2735 A **Deque (Double-Ended Queue)** allows insertion and deletion from both ends — front and rear. It is implemented here using a doubly linked list, so both `prev` and `next` pointers are updated during insert/delete at either end.
   2736 ### Algorithm:
   2737 **Check Empty:**
   2738 ```
   2739 procedure isEmpty(front)
   2740 begin
   2741 	if(front = NULL)
   2742 		return true;
   2743 	else
   2744 		return false;
   2745 	end if
   2746 end procedure
   2747 ```
   2748 
   2749 **Insert at Front:**
   2750 ```
   2751 procedure insertFront(front, rear, val)
   2752 begin
   2753 	newNode ← create new node;
   2754 	newNode.data ← val;
   2755 	newNode.prev ← NULL;
   2756 	newNode.next ← front;
   2757 	if(isEmpty(front))
   2758 		front ← newNode;
   2759 		rear ← newNode;
   2760 	else
   2761 		front.prev ← newNode;
   2762 		front ← newNode;
   2763 	end if
   2764 end procedure
   2765 ```
   2766 
   2767 **Insert at Rear:**
   2768 ```
   2769 procedure insertRear(front, rear, val)
   2770 begin
   2771 	newNode ← create new node;
   2772 	newNode.data ← val;
   2773 	newNode.next ← NULL;
   2774 	newNode.prev ← rear;
   2775 	if(isEmpty(front))
   2776 		front ← newNode;
   2777 		rear ← newNode;
   2778 	else
   2779 		rear.next ← newNode;
   2780 		rear ← newNode;
   2781 	end if
   2782 end procedure
   2783 ```
   2784 
   2785 **Delete from Front:**
   2786 ```
   2787 procedure deleteFront(front, rear)
   2788 begin
   2789 	if(isEmpty(front))
   2790 		print "Deque Underflow";
   2791 		return;
   2792 	end if
   2793 	temp ← front;
   2794 	val ← temp.data;
   2795 	front ← front.next;
   2796 	if(front = NULL)
   2797 		rear ← NULL;
   2798 	else
   2799 		front.prev ← NULL;
   2800 	end if
   2801 	free temp;
   2802 	return val;
   2803 end procedure
   2804 ```
   2805 
   2806 **Delete from Rear:**
   2807 ```
   2808 procedure deleteRear(front, rear)
   2809 begin
   2810 	if(isEmpty(front))
   2811 		print "Deque Underflow";
   2812 		return;
   2813 	end if
   2814 	temp ← rear;
   2815 	val ← temp.data;
   2816 	rear ← rear.prev;
   2817 	if(rear = NULL)
   2818 		front ← NULL;
   2819 	else
   2820 		rear.next ← NULL;
   2821 	end if
   2822 	free temp;
   2823 	return val;
   2824 end procedure
   2825 ```
   2826 
   2827 **Get Front / Get Rear:**
   2828 ```
   2829 procedure getFront(front)
   2830 begin
   2831 	if(isEmpty(front))
   2832 		print "Deque is empty";
   2833 		return;
   2834 	end if
   2835 	return front.data;
   2836 end procedure
   2837 
   2838 procedure getRear(rear)
   2839 begin
   2840 	if(rear = NULL)
   2841 		print "Deque is empty";
   2842 		return;
   2843 	end if
   2844 	return rear.data;
   2845 end procedure
   2846 ```
   2847 
   2848 ### Source Code:
   2849 ```
   2850 #include <iostream>
   2851 using namespace std;
   2852 
   2853 struct node {
   2854     int data;
   2855     node *prev = nullptr;
   2856     node *next = nullptr;
   2857 };
   2858 
   2859 class Deque {
   2860 private:
   2861     node *front, *rear;
   2862 
   2863 public:
   2864     Deque() { front = nullptr; rear = nullptr; }
   2865     bool isEmpty() { return (front == nullptr); }
   2866 
   2867     void insertFront() {
   2868         node *newNode = new node;
   2869         cout << "Enter the value: ";
   2870         cin >> newNode->data;
   2871         newNode->prev = nullptr;
   2872         newNode->next = front;
   2873         if (isEmpty()) front = rear = newNode;
   2874         else { front->prev = newNode; front = newNode; }
   2875     }
   2876 
   2877     void insertRear() {
   2878         node *newNode = new node;
   2879         cout << "Enter the value: ";
   2880         cin >> newNode->data;
   2881         newNode->next = nullptr;
   2882         newNode->prev = rear;
   2883         if (isEmpty()) front = rear = newNode;
   2884         else { rear->next = newNode; rear = newNode; }
   2885     }
   2886 
   2887     void deleteFront() {
   2888         if (isEmpty()) { cout << "Deque Underflow!\n"; return; }
   2889         node *temp = front;
   2890         int val = temp->data;
   2891         front = front->next;
   2892         if (front == nullptr) rear = nullptr;
   2893         else front->prev = nullptr;
   2894         delete temp;
   2895         cout << "Deleted from front: " << val << endl;
   2896     }
   2897 
   2898     void deleteRear() {
   2899         if (isEmpty()) { cout << "Deque Underflow!\n"; return; }
   2900         node *temp = rear;
   2901         int val = temp->data;
   2902         rear = rear->prev;
   2903         if (rear == nullptr) front = nullptr;
   2904         else rear->next = nullptr;
   2905         delete temp;
   2906         cout << "Deleted from rear: " << val << endl;
   2907     }
   2908 
   2909     void getFront() {
   2910         if (isEmpty()) { cout << "Deque is empty!\n"; return; }
   2911         cout << "Front element: " << front->data << endl;
   2912     }
   2913 
   2914     void getRear() {
   2915         if (isEmpty()) { cout << "Deque is empty!\n"; return; }
   2916         cout << "Rear element: " << rear->data << endl;
   2917     }
   2918 
   2919     void display() {
   2920         if (isEmpty()) { cout << "Deque is empty!\n"; return; }
   2921         node *temp = front;
   2922         while (temp != nullptr) { cout << temp->data << " "; temp = temp->next; }
   2923         cout << endl;
   2924     }
   2925 
   2926     ~Deque() {
   2927         node *temp;
   2928         while (front != nullptr) { temp = front; front = front->next; delete temp; }
   2929     }
   2930 };
   2931 
   2932 int main() {
   2933     Deque dq;
   2934     int choice;
   2935 
   2936     while (true) {
   2937         cout << "1.insertFront 2.insertRear 3.deleteFront 4.deleteRear\n"
   2938              << "5.getFront 6.getRear 7.isEmpty 0.Display -1.Exit\n";
   2939         cout << "Enter your choice: ";
   2940         cin >> choice;
   2941 
   2942         switch (choice) {
   2943             case 1: dq.insertFront(); break;
   2944             case 2: dq.insertRear(); break;
   2945             case 3: dq.deleteFront(); break;
   2946             case 4: dq.deleteRear(); break;
   2947             case 5: dq.getFront(); break;
   2948             case 6: dq.getRear(); break;
   2949             case 7: cout << (dq.isEmpty() ? "Empty\n" : "Not empty\n"); break;
   2950             case 0: dq.display(); break;
   2951             case -1: cout << "Exiting...\n"; return 0;
   2952             default: cout << "Wrong choice.\n";
   2953         }
   2954     }
   2955 }
   2956 ```
   2957 ///
   2958 ### Output:
   2959 ![[Pasted image 20260923193206.png]]
   2960 ### Discussion:
   2961 - **insertFront()/insertRear()** create a new node and link it at the respective end, updating both `prev` and `next` pointers of neighboring nodes to maintain the doubly linked structure.
   2962 - **deleteFront()/deleteRear()** remove the node at the respective end by advancing `front` or `rear` to the adjacent node and clearing the freed node's neighbor pointer, with `front`/`rear` both reset to `NULL` if the deque becomes empty.
   2963 - **getFront()/getRear()** simply return `front->data` or `rear->data` without modifying the deque.
   2964 
   2965 ///
   2966 ## Assignment 13
   2967 ### Problem Statement:
   2968 Write a program to scan a polynomial using a linked list and add two polynomials.
   2969 ### Problem Defination:
   2970 A **Polynomial** can be represented as a linked list of terms, where each node stores a `coeff` (coefficient) and `exp` (exponent), sorted in decreasing order of exponent.
   2971 - **insertTerm:** Inserts a term into the list in the correct sorted position, merging with an existing term of the same exponent.
   2972 - **Addition:** Two polynomials are added by traversing both lists simultaneously, comparing exponents, and combining coefficients of matching terms.
   2973 ### Algorithm:
   2974 **Insert Term in Sorted Order:**
   2975 ```
   2976 procedure insertTerm(head, coeff, exp)
   2977 begin
   2978 	if(coeff = 0)
   2979 		return;
   2980 	end if
   2981 	newNode ← create new node;
   2982 	newNode.coeff ← coeff;
   2983 	newNode.exp ← exp;
   2984 	newNode.next ← NULL;
   2985 	if(head = NULL or exp > head.exp)
   2986 		newNode.next ← head;
   2987 		head ← newNode;
   2988 		return;
   2989 	end if
   2990 	if(head.exp = exp)
   2991 		head.coeff ← head.coeff + coeff;
   2992 		free newNode;
   2993 		return;
   2994 	end if
   2995 	temp ← head;
   2996 	while(temp.next ≠ NULL and temp.next.exp > exp) do
   2997 		temp ← temp.next;
   2998 	end while
   2999 	if(temp.next ≠ NULL and temp.next.exp = exp)
   3000 		temp.next.coeff ← temp.next.coeff + coeff;
   3001 		free newNode;
   3002 	else
   3003 		newNode.next ← temp.next;
   3004 		temp.next ← newNode;
   3005 	end if
   3006 end procedure
   3007 ```
   3008 
   3009 **Add Polynomials:**
   3010 ```
   3011 procedure addPolynomials(head1, head2, resultHead)
   3012 begin
   3013 	p ← head1;
   3014 	q ← head2;
   3015 	while(p ≠ NULL and q ≠ NULL) do
   3016 		if(p.exp = q.exp)
   3017 			sum ← p.coeff + q.coeff;
   3018 			if(sum ≠ 0)
   3019 				call insertTerm(resultHead, sum, p.exp);
   3020 			end if
   3021 			p ← p.next;
   3022 			q ← q.next;
   3023 		else if(p.exp > q.exp)
   3024 			call insertTerm(resultHead, p.coeff, p.exp);
   3025 			p ← p.next;
   3026 		else
   3027 			call insertTerm(resultHead, q.coeff, q.exp);
   3028 			q ← q.next;
   3029 		end if
   3030 	end while
   3031 	while(p ≠ NULL) do
   3032 		call insertTerm(resultHead, p.coeff, p.exp);
   3033 		p ← p.next;
   3034 	end while
   3035 	while(q ≠ NULL) do
   3036 		call insertTerm(resultHead, q.coeff, q.exp);
   3037 		q ← q.next;
   3038 	end while
   3039 end procedure
   3040 ```
   3041 
   3042 ### Source Code:
   3043 ```
   3044 #include <iostream>
   3045 #include <cmath>
   3046 using namespace std;
   3047 
   3048 struct node {
   3049     int coeff, exp;
   3050     node *next = nullptr;
   3051 };
   3052 
   3053 class Polynomial {
   3054 private:
   3055     node *head;
   3056 
   3057     void clear() {
   3058         node *temp;
   3059         while (head != nullptr) {
   3060             temp = head;
   3061             head = head->next;
   3062             delete temp;
   3063         }
   3064     }
   3065 
   3066     void copyFrom(const Polynomial &other) {
   3067         if (other.head == nullptr) {
   3068             head = nullptr;
   3069             return;
   3070         }
   3071         head = new node{other.head->coeff, other.head->exp, nullptr};
   3072         node *current = head;
   3073         node *otherCurrent = other.head->next;
   3074         while (otherCurrent != nullptr) {
   3075             current->next = new node{otherCurrent->coeff, otherCurrent->exp, nullptr};
   3076             current = current->next;
   3077             otherCurrent = otherCurrent->next;
   3078         }
   3079     }
   3080 
   3081 public:
   3082     Polynomial() { head = nullptr; }
   3083 
   3084     Polynomial(const Polynomial &other) {
   3085         copyFrom(other);
   3086     }
   3087 
   3088     Polynomial& operator=(const Polynomial &other) {
   3089         if (this != &other) {
   3090             clear();
   3091             copyFrom(other);
   3092         }
   3093         return *this;
   3094     }
   3095 
   3096     ~Polynomial() {
   3097         clear();
   3098     }
   3099 
   3100     void insertTerm(int coeff, int exp) {
   3101         if (coeff == 0) return;
   3102         node *newNode = new node{coeff, exp, nullptr};
   3103 
   3104         if (head == nullptr || exp > head->exp) {
   3105             newNode->next = head;
   3106             head = newNode;
   3107             return;
   3108         }
   3109         if (head->exp == exp) {
   3110             head->coeff += coeff;
   3111             delete newNode;
   3112             if (head->coeff == 0) {
   3113                 node* temp = head;
   3114                 head = head->next;
   3115                 delete temp;
   3116             }
   3117             return;
   3118         }
   3119         node *temp = head;
   3120         while (temp->next != nullptr && temp->next->exp > exp) temp = temp->next;
   3121         if (temp->next != nullptr && temp->next->exp == exp) {
   3122             temp->next->coeff += coeff;
   3123             delete newNode;
   3124             if (temp->next->coeff == 0) {
   3125                 node* toDelete = temp->next;
   3126                 temp->next = temp->next->next;
   3127                 delete toDelete;
   3128             }
   3129         } else {
   3130             newNode->next = temp->next;
   3131             temp->next = newNode;
   3132         }
   3133     }
   3134 
   3135     void inputPolynomial() {
   3136         int n, coeff, exp;
   3137         cout << "Enter number of terms: ";
   3138         cin >> n;
   3139         for (int i = 0; i < n; i++) {
   3140             cout << "Coefficient: "; cin >> coeff;
   3141             cout << "Exponent: "; cin >> exp;
   3142             insertTerm(coeff, exp);
   3143         }
   3144     }
   3145 
   3146     Polynomial add(const Polynomial &other) const {
   3147         Polynomial result;
   3148         node *p = head, *q = other.head;
   3149         while (p != nullptr && q != nullptr) {
   3150             if (p->exp == q->exp) {
   3151                 int sum = p->coeff + q->coeff;
   3152                 if (sum != 0) result.insertTerm(sum, p->exp);
   3153                 p = p->next; q = q->next;
   3154             } else if (p->exp > q->exp) {
   3155                 result.insertTerm(p->coeff, p->exp);
   3156                 p = p->next;
   3157             } else {
   3158                 result.insertTerm(q->coeff, q->exp);
   3159                 q = q->next;
   3160             }
   3161         }
   3162         while (p != nullptr) { result.insertTerm(p->coeff, p->exp); p = p->next; }
   3163         while (q != nullptr) { result.insertTerm(q->coeff, q->exp); q = q->next; }
   3164         return result;
   3165     }
   3166 
   3167     void display() const {
   3168         if (head == nullptr) { cout << "0\n"; return; }
   3169         node *temp = head;
   3170         bool first = true;
   3171         while (temp != nullptr) {
   3172             if (!first && temp->coeff > 0) cout << " + ";
   3173             else if (!first && temp->coeff < 0) cout << " - ";
   3174             else if (temp->coeff < 0) cout << "-";
   3175             int c = abs(temp->coeff);
   3176             if (temp->exp == 0) cout << c;
   3177             else if (temp->exp == 1) cout << (c == 1 ? "x" : to_string(c) + "x");
   3178             else cout << (c == 1 ? "x^" + to_string(temp->exp) : to_string(c) + "x^" + to_string(temp->exp));
   3179             first = false;
   3180             temp = temp->next;
   3181         }
   3182         cout << endl;
   3183     }
   3184 };
   3185 
   3186 int main() {
   3187     Polynomial p1, p2, result;
   3188     cout << "--- First Polynomial ---\n";
   3189     p1.inputPolynomial();
   3190     cout << "--- Second Polynomial ---\n";
   3191     p2.inputPolynomial();
   3192 
   3193     cout << "First: "; p1.display();
   3194     cout << "Second: "; p2.display();
   3195 
   3196     result = p1.add(p2);
   3197     cout << "Sum: "; result.display();
   3198     return 0;
   3199 }
   3200 ```
   3201 
   3202 ### Output:
   3203 ![[Pasted image 20260923194003.png]]
   3204 
   3205 ### Discussion:
   3206 - **insertTerm()** inserts a term into the correct sorted-by-exponent position, merging its coefficient into an existing node if a term with the same exponent already exists, and discarding it entirely if the resulting coefficient is zero.
   3207 - **add()** walks both polynomial lists in parallel, comparing exponents at each step: matching exponents have their coefficients summed, while the term with the higher exponent is copied over as-is, until one list is exhausted and the rest of the other is appended — producing a new sorted result polynomial.
   3208 
   3209 ///
   3210 ## Assignment 14
   3211 ### Problem Statement:
   3212 Write a program to calculate factorial and to compute the factors of a given number using (i) recursion and (ii) iteration.
   3213 ### Problem Defination:
   3214 - **Factorial (n!):** Product of all positive integers up to `n`. Recursive definition: `n! = n * (n-1)!`, with base case `0! = 1! = 1`.
   3215 - **Factors:** Numbers that divide `n` exactly (remainder 0). Can be found either by recursively checking divisors from 1 to `n`, or with a simple iterative loop.
   3216 ### Algorithm:
   3217 **Factorial using Recursion:**
   3218 ```
   3219 procedure factorialRecursive(n)
   3220 begin
   3221 	if(n <= 1)
   3222 		return 1;
   3223 	else
   3224 		return n * factorialRecursive(n - 1);
   3225 	end if
   3226 end procedure
   3227 ```
   3228 
   3229 **Factorial using Iteration:**
   3230 ```
   3231 procedure factorialIterative(n)
   3232 begin
   3233 	fact ← 1;
   3234 	for i ← 2 to n do
   3235 		fact ← fact * i;
   3236 	end for
   3237 	return fact;
   3238 end procedure
   3239 ```
   3240 
   3241 **Factors using Recursion:**
   3242 ```
   3243 procedure factorsRecursive(n, divisor)
   3244 begin
   3245 	if(divisor > n)
   3246 		return;
   3247 	end if
   3248 	if(n mod divisor = 0)
   3249 		print divisor + " ";
   3250 	end if
   3251 	call factorsRecursive(n, divisor + 1);
   3252 end procedure
   3253 ```
   3254 
   3255 **Factors using Iteration:**
   3256 ```
   3257 procedure factorsIterative(n)
   3258 begin
   3259 	for i ← 1 to n do
   3260 		if(n mod i = 0)
   3261 			print i + " ";
   3262 		end if
   3263 	end for
   3264 end procedure
   3265 ```
   3266 
   3267 ### Source Code:
   3268 ```
   3269 #include <iostream>
   3270 using namespace std;
   3271 
   3272 class MathOperations {
   3273 private:
   3274     int num;
   3275 
   3276     long long factorialRecursive(int n) {
   3277         if (n <= 1) return 1;
   3278         return n * factorialRecursive(n - 1);
   3279     }
   3280 
   3281     void factorsRecursive(int n, int divisor) {
   3282         if (divisor > n) return;
   3283         if (n % divisor == 0) cout << divisor << " ";
   3284         factorsRecursive(n, divisor + 1);
   3285     }
   3286 
   3287 public:
   3288     MathOperations(int n) { num = n; }
   3289 
   3290     void calculateFactorialRecursive() {
   3291         if (num < 0) { cout << "Not defined for negative numbers.\n"; return; }
   3292         cout << "Factorial (Recursive): " << factorialRecursive(num) << endl;
   3293     }
   3294 
   3295     void calculateFactorialIterative() {
   3296         if (num < 0) { cout << "Not defined for negative numbers.\n"; return; }
   3297         long long fact = 1;
   3298         for (int i = 2; i <= num; i++) fact *= i;
   3299         cout << "Factorial (Iterative): " << fact << endl;
   3300     }
   3301 
   3302     void computeFactorsRecursive() {
   3303         if (num <= 0) { cout << "Factors need a positive integer.\n"; return; }
   3304         cout << "Factors (Recursive): ";
   3305         factorsRecursive(num, 1);
   3306         cout << endl;
   3307     }
   3308 
   3309     void computeFactorsIterative() {
   3310         if (num <= 0) { cout << "Factors need a positive integer.\n"; return; }
   3311         cout << "Factors (Iterative): ";
   3312         for (int i = 1; i <= num; i++) if (num % i == 0) cout << i << " ";
   3313         cout << endl;
   3314     }
   3315 };
   3316 
   3317 int main() {
   3318     int n, choice;
   3319     cout << "Enter a number: ";
   3320     cin >> n;
   3321     MathOperations op(n);
   3322 
   3323     while (true) {
   3324         cout << "1.Factorial(Recursive) 2.Factorial(Iterative) "
   3325              << "3.Factors(Recursive) 4.Factors(Iterative) 0.Change Number -1.Exit\n";
   3326         cout << "Enter your choice: ";
   3327         cin >> choice;
   3328 
   3329         switch (choice) {
   3330             case 1: op.calculateFactorialRecursive(); break;
   3331             case 2: op.calculateFactorialIterative(); break;
   3332             case 3: op.computeFactorsRecursive(); break;
   3333             case 4: op.computeFactorsIterative(); break;
   3334             case 0: cout << "Enter new number: "; cin >> n; op = MathOperations(n); break;
   3335             case -1: cout << "Exiting...\n"; return 0;
   3336             default: cout << "Wrong choice.\n";
   3337         }
   3338     }
   3339 }
   3340 ```
   3341 ///
   3342 ### Output:
   3343 ![[Pasted image 20260923195210.png]]
   3344 
   3345 ### Discussion:
   3346 - **factorialRecursive()** breaks the problem down as `n * factorial(n-1)`, terminating at the base case `n <= 1`, building up the result through the call stack as it unwinds.
   3347 - **factorialIterative()** achieves the same result with a simple loop multiplying `fact` by each integer from 2 to `n`, avoiding recursive call overhead.
   3348 - **factorsRecursive()** checks divisibility for the current `divisor` and recurses with `divisor + 1` until it exceeds `n`, printing each valid divisor along the way.
   3349 - **factorsIterative()** performs the same check using a single `for` loop from 1 to `n`.
   3350 
   3351 ///
   3352 ## Assignment 15
   3353 ### Problem Statement:
   3354 Write a program to display the Fibonacci series using (i) recursion and (ii) iteration.
   3355 ### Problem Defination:
   3356 The **Fibonacci series** is a sequence where each term is the sum of the two preceding ones (`0, 1, 1, 2, 3, 5, ...`), defined recursively as `F(n) = F(n-1) + F(n-2)` with base cases `F(0) = 0` and `F(1) = 1`.
   3357 ### Algorithm:
   3358 **Fibonacci Term using Recursion:**
   3359 ```
   3360 procedure fibRecursive(k)
   3361 begin
   3362 	if(k <= 0)
   3363 		return 0;
   3364 	end if
   3365 	if(k = 1)
   3366 		return 1;
   3367 	end if
   3368 	return fibRecursive(k - 1) + fibRecursive(k - 2);
   3369 end procedure
   3370 ```
   3371 
   3372 **Fibonacci Series using Iteration:**
   3373 ```
   3374 procedure fibIterative(n)
   3375 begin
   3376 	if(n <= 0)
   3377 		return;
   3378 	end if
   3379 	first ← 0;
   3380 	second ← 1;
   3381 	for i ← 0 to n - 1 do
   3382 		if(i = 0)
   3383 			print first + " ";
   3384 		else if(i = 1)
   3385 			print second + " ";
   3386 		else
   3387 			nextTerm ← first + second;
   3388 			print nextTerm + " ";
   3389 			first ← second;
   3390 			second ← nextTerm;
   3391 		end if
   3392 	end for
   3393 end procedure
   3394 ```
   3395 
   3396 ### Source Code:
   3397 ```
   3398 #include <iostream>
   3399 using namespace std;
   3400 
   3401 class Fibonacci {
   3402 private:
   3403     int n;
   3404 
   3405     int fibRecursive(int k) {
   3406         if (k <= 0) return 0;
   3407         if (k == 1) return 1;
   3408         return fibRecursive(k - 1) + fibRecursive(k - 2);
   3409     }
   3410 
   3411 public:
   3412     Fibonacci(int count) { n = count; }
   3413 
   3414     void displayRecursive() {
   3415         cout << "Fibonacci (Recursive): ";
   3416         for (int i = 0; i < n; i++) cout << fibRecursive(i) << " ";
   3417         cout << endl;
   3418     }
   3419 
   3420     void displayIterative() {
   3421         cout << "Fibonacci (Iterative): ";
   3422         if (n <= 0) { cout << endl; return; }
   3423         int first = 0, second = 1;
   3424         for (int i = 0; i < n; i++) {
   3425             if (i == 0) cout << first << " ";
   3426             else if (i == 1) cout << second << " ";
   3427             else {
   3428                 int nextTerm = first + second;
   3429                 cout << nextTerm << " ";
   3430                 first = second;
   3431                 second = nextTerm;
   3432             }
   3433         }
   3434         cout << endl;
   3435     }
   3436 };
   3437 
   3438 int main() {
   3439     int n, choice;
   3440     cout << "Enter number of terms: ";
   3441     cin >> n;
   3442     if (n < 0) { cout << "Invalid number of terms!\n"; return 0; }
   3443 
   3444     Fibonacci fib(n);
   3445     while (true) {
   3446         cout << "1.Recursive 2.Iterative -1.Exit\n";
   3447         cout << "Enter your choice: ";
   3448         cin >> choice;
   3449 
   3450         switch (choice) {
   3451             case 1: fib.displayRecursive(); break;
   3452             case 2: fib.displayIterative(); break;
   3453             case -1: cout << "Exiting...\n"; return 0;
   3454             default: cout << "Wrong choice.\n";
   3455         }
   3456     }
   3457 }
   3458 ```
   3459 
   3460 ### Output:
   3461 ![[Pasted image 20260923195554.png|484]]
   3462 
   3463 ### Discussion:
   3464 - **fibRecursive()** computes the k-th term by recursively summing the two preceding terms, with base cases returning `0` and `1` for `k <= 0` and `k = 1` respectively — called once per term for the recursive display.
   3465 - **displayIterative()** builds the series in a single pass using two tracking variables, `first` and `second`, updating them each iteration to hold the last two computed terms, avoiding the exponential recomputation of the recursive approach.
   3466 
   3467 ///
   3468 ## Assignment 16
   3469 ### Problem Statement:
   3470 WAP to create a Binary Search Tree and include following operations in tree:
   3471 i. Insertion (Recursive and Iterative Implementation) 
   3472 ii. Deletion by copying 
   3473 iii. Deletion by Merging 
   3474 iv. Search a no. in BST 
   3475 v. Display its preorder, postorder and inorder traversals Recursively 
   3476 vi. Display its preorder, postorder and inorder traversals Iteratively 
   3477 vii. Display its level-by-level traversals 
   3478 viii. Count the non-leaf nodes and leaf nodes 
   3479 ix. Display height of tree 
   3480 x. Create a mirror image of tree 
   3481 xi. Check whether two BSTs are equal or not
   3482 ### Problem Defination:
   3483 A **Binary Search Tree (BST)** is a binary tree in which every node's left subtree contains only values smaller than the node, and the right subtree contains only values larger. Key operations include **insertion**, **deletion** (by copying the inorder predecessor or by merging subtrees), **search**, and **traversals** (preorder, inorder, postorder, level order) to visit all nodes in different orders.
   3484 ### Algorithm:
   3485 **Recursive Insertion:**
   3486 ```
   3487 procedure insertRecursive(root, val)
   3488 begin
   3489 	if(root = NULL)
   3490 		newNode ← create new node with val;
   3491 		return newNode;
   3492 	end if
   3493 	if(val < root.data)
   3494 		root.left ← insertRecursive(root.left, val);
   3495 	else if(val > root.data)
   3496 		root.right ← insertRecursive(root.right, val);
   3497 	else
   3498 		print "Duplicate value ignored";
   3499 	end if
   3500 	return root;
   3501 end procedure
   3502 ```
   3503 
   3504 **Iterative Insertion:**
   3505 ```
   3506 procedure insertIterative(root, val)
   3507 begin
   3508 	newNode ← create new node with val;
   3509 	if(root = NULL)
   3510 		root ← newNode;
   3511 		return;
   3512 	end if
   3513 	current ← root;
   3514 	parent ← NULL;
   3515 	while(current ≠ NULL) do
   3516 		parent ← current;
   3517 		if(val < current.data)
   3518 			current ← current.left;
   3519 		else if(val > current.data)
   3520 			current ← current.right;
   3521 		else
   3522 			print "Duplicate value ignored";
   3523 			free newNode;
   3524 			return;
   3525 		end if
   3526 	end while
   3527 	if(val < parent.data)
   3528 		parent.left ← newNode;
   3529 	else
   3530 		parent.right ← newNode;
   3531 	end if
   3532 end procedure
   3533 ```
   3534 
   3535 **Search:**
   3536 ```
   3537 procedure search(root, key)
   3538 begin
   3539 	current ← root;
   3540 	while(current ≠ NULL) do
   3541 		if(current.data = key)
   3542 			return true;
   3543 		else if(key < current.data)
   3544 			current ← current.left;
   3545 		else
   3546 			current ← current.right;
   3547 		end if
   3548 	end while
   3549 	return false;
   3550 end procedure
   3551 ```
   3552 
   3553 **Deletion by Copying:**
   3554 ```
   3555 procedure deleteByCopying(root, key)
   3556 begin
   3557 	if(root = NULL)
   3558 		return NULL;
   3559 	end if
   3560 	if(key < root.data)
   3561 		root.left ← deleteByCopying(root.left, key);
   3562 	else if(key > root.data)
   3563 		root.right ← deleteByCopying(root.right, key);
   3564 	else
   3565 		if(root.left = NULL)
   3566 			temp ← root.right;
   3567 			free root;
   3568 			return temp;
   3569 		else if(root.right = NULL)
   3570 			temp ← root.left;
   3571 			free root;
   3572 			return temp;
   3573 		end if
   3574 		pred ← root.left;
   3575 		while(pred.right ≠ NULL) do
   3576 			pred ← pred.right;
   3577 		end while
   3578 		root.data ← pred.data;
   3579 		root.left ← deleteByCopying(root.left, pred.data);
   3580 	end if
   3581 	return root;
   3582 end procedure
   3583 ```
   3584 
   3585 **Deletion by Merging:**
   3586 ```
   3587 procedure deleteByMerging(root, key)
   3588 begin
   3589 	if(root = NULL)
   3590 		return NULL;
   3591 	end if
   3592 	if(key < root.data)
   3593 		root.left ← deleteByMerging(root.left, key);
   3594 		return root;
   3595 	else if(key > root.data)
   3596 		root.right ← deleteByMerging(root.right, key);
   3597 		return root;
   3598 	end if
   3599 	if(root.left = NULL)
   3600 		temp ← root.right;
   3601 		free root;
   3602 		return temp;
   3603 	else if(root.right = NULL)
   3604 		temp ← root.left;
   3605 		free root;
   3606 		return temp;
   3607 	end if
   3608 	successor ← root.right;
   3609 	while(successor.left ≠ NULL) do
   3610 		successor ← successor.left;
   3611 	end while
   3612 	successor.left ← root.left;
   3613 	temp ← root.right;
   3614 	free root;
   3615 	return temp;
   3616 end procedure
   3617 ```
   3618 
   3619 **Preorder Traversal (Recursive):**
   3620 ```
   3621 procedure preorderRecursive(root)
   3622 begin
   3623 	if(root = NULL)
   3624 		return;
   3625 	end if
   3626 	print root.data + " ";
   3627 	call preorderRecursive(root.left);
   3628 	call preorderRecursive(root.right);
   3629 end procedure
   3630 ```
   3631 
   3632 **Inorder Traversal (Recursive):**
   3633 ```
   3634 procedure inorderRecursive(root)
   3635 begin
   3636 	if(root = NULL)
   3637 		return;
   3638 	end if
   3639 	call inorderRecursive(root.left);
   3640 	print root.data + " ";
   3641 	call inorderRecursive(root.right);
   3642 end procedure
   3643 ```
   3644 
   3645 **Postorder Traversal (Recursive):**
   3646 ```
   3647 procedure postorderRecursive(root)
   3648 begin
   3649 	if(root = NULL)
   3650 		return;
   3651 	end if
   3652 	call postorderRecursive(root.left);
   3653 	call postorderRecursive(root.right);
   3654 	print root.data + " ";
   3655 end procedure
   3656 ```
   3657 
   3658 **Preorder Traversal (Iterative):**
   3659 ```
   3660 procedure preorderIterative(root)
   3661 begin
   3662 	if(root = NULL)
   3663 		return;
   3664 	end if
   3665 	initialize stack S;
   3666 	push(S, root);
   3667 	while(not isEmpty(S)) do
   3668 		current ← pop(S);
   3669 		print current.data + " ";
   3670 		if(current.right ≠ NULL)
   3671 			push(S, current.right);
   3672 		end if
   3673 		if(current.left ≠ NULL)
   3674 			push(S, current.left);
   3675 		end if
   3676 	end while
   3677 end procedure
   3678 ```
   3679 
   3680 **Inorder Traversal (Iterative):**
   3681 ```
   3682 procedure inorderIterative(root)
   3683 begin
   3684 	if(root = NULL)
   3685 		return;
   3686 	end if
   3687 	initialize stack S;
   3688 	current ← root;
   3689 	while(current ≠ NULL or not isEmpty(S)) do
   3690 		while(current ≠ NULL) do
   3691 			push(S, current);
   3692 			current ← current.left;
   3693 		end while
   3694 		current ← pop(S);
   3695 		print current.data + " ";
   3696 		current ← current.right;
   3697 	end while
   3698 end procedure
   3699 ```
   3700 
   3701 **Postorder Traversal (Iterative):**
   3702 ```
   3703 procedure postorderIterative(root)
   3704 begin
   3705 	if(root = NULL)
   3706 		return;
   3707 	end if
   3708 	initialize stacks S1, S2;
   3709 	push(S1, root);
   3710 	while(not isEmpty(S1)) do
   3711 		current ← pop(S1);
   3712 		push(S2, current);
   3713 		if(current.left ≠ NULL)
   3714 			push(S1, current.left);
   3715 		end if
   3716 		if(current.right ≠ NULL)
   3717 			push(S1, current.right);
   3718 		end if
   3719 	end while
   3720 	while(not isEmpty(S2)) do
   3721 		current ← pop(S2);
   3722 		print current.data + " ";
   3723 	end while
   3724 end procedure
   3725 ```
   3726 
   3727 **Level Order Traversal:**
   3728 ```
   3729 procedure levelOrder(root)
   3730 begin
   3731 	if(root = NULL)
   3732 		return;
   3733 	end if
   3734 	initialize queue Q;
   3735 	enqueue(Q, root);
   3736 	while(not isEmpty(Q)) do
   3737 		current ← dequeue(Q);
   3738 		print current.data + " ";
   3739 		if(current.left ≠ NULL)
   3740 			enqueue(Q, current.left);
   3741 		end if
   3742 		if(current.right ≠ NULL)
   3743 			enqueue(Q, current.right);
   3744 		end if
   3745 	end while
   3746 end procedure
   3747 ```
   3748 
   3749 **Count Leaf Nodes:**
   3750 ```
   3751 procedure countLeaf(root)
   3752 begin
   3753 	if(root = NULL)
   3754 		return 0;
   3755 	end if
   3756 	if(root.left = NULL and root.right = NULL)
   3757 		return 1;
   3758 	end if
   3759 	return countLeaf(root.left) + countLeaf(root.right);
   3760 end procedure
   3761 ```
   3762 
   3763 **Count Non-Leaf Nodes:**
   3764 ```
   3765 procedure countNonLeaf(root)
   3766 begin
   3767 	if(root = NULL or (root.left = NULL and root.right = NULL))
   3768 		return 0;
   3769 	end if
   3770 	return 1 + countNonLeaf(root.left) + countNonLeaf(root.right);
   3771 end procedure
   3772 ```
   3773 
   3774 **Calculate Height:**
   3775 ```
   3776 procedure height(root)
   3777 begin
   3778 	if(root = NULL)
   3779 		return -1;
   3780 	end if
   3781 	leftHeight ← height(root.left);
   3782 	rightHeight ← height(root.right);
   3783 	return 1 + max(leftHeight, rightHeight);
   3784 end procedure
   3785 ```
   3786 
   3787 **Mirror Image:**
   3788 ```
   3789 procedure mirror(root)
   3790 begin
   3791 	if(root = NULL)
   3792 		return;
   3793 	end if
   3794 	temp ← root.left;
   3795 	root.left ← root.right;
   3796 	root.right ← temp;
   3797 	call mirror(root.left);
   3798 	call mirror(root.right);
   3799 end procedure
   3800 ```
   3801 
   3802 **Check Trees Equal:**
   3803 ```
   3804 procedure areEqual(root1, root2)
   3805 begin
   3806 	if(root1 = NULL and root2 = NULL)
   3807 		return true;
   3808 	end if
   3809 	if(root1 = NULL or root2 = NULL)
   3810 		return false;
   3811 	end if
   3812 	if(root1.data ≠ root2.data)
   3813 		return false;
   3814 	end if
   3815 	return areEqual(root1.left, root2.left) and areEqual(root1.right, root2.right);
   3816 end procedure
   3817 ```
   3818 
   3819 ### Source Code:
   3820 ```
   3821 #include <iostream>
   3822 #include <stack>
   3823 #include <queue>
   3824 #include <algorithm>
   3825 
   3826 using namespace std;
   3827 
   3828 struct node {
   3829     int data;
   3830     node *left;
   3831     node *right;
   3832 
   3833     node(int val) {
   3834         data = val;
   3835         left = nullptr;
   3836         right = nullptr;
   3837     }
   3838 };
   3839 
   3840 class BST {
   3841 private:
   3842     node *root;
   3843 
   3844     node* insertRecursive(node *current, int val, bool &inserted) {
   3845         if (current == nullptr) {
   3846             inserted = true;
   3847             return new node(val);
   3848         }
   3849         if (val < current->data) current->left = insertRecursive(current->left, val, inserted);
   3850         else if (val > current->data) current->right = insertRecursive(current->right, val, inserted);
   3851         else { cout << "Duplicate value ignored.\n"; inserted = false; }
   3852         return current;
   3853     }
   3854 
   3855     void preorderRecursive(node *current) {
   3856         if (current == nullptr) return;
   3857         cout << current->data << " ";
   3858         preorderRecursive(current->left);
   3859         preorderRecursive(current->right);
   3860     }
   3861 
   3862     void inorderRecursive(node *current) {
   3863         if (current == nullptr) return;
   3864         inorderRecursive(current->left);
   3865         cout << current->data << " ";
   3866         inorderRecursive(current->right);
   3867     }
   3868 
   3869     void postorderRecursive(node *current) {
   3870         if (current == nullptr) return;
   3871         postorderRecursive(current->left);
   3872         postorderRecursive(current->right);
   3873         cout << current->data << " ";
   3874     }
   3875 
   3876     bool searchRecursive(node *current, int key) {
   3877         if (current == nullptr) return false;
   3878         if (current->data == key) return true;
   3879         if (key < current->data) return searchRecursive(current->left, key);
   3880         return searchRecursive(current->right, key);
   3881     }
   3882 
   3883     node* deleteByCopying(node *current, int key) {
   3884         if (current == nullptr) return nullptr;
   3885         if (key < current->data) {
   3886             current->left = deleteByCopying(current->left, key);
   3887         } else if (key > current->data) {
   3888             current->right = deleteByCopying(current->right, key);
   3889         } else {
   3890             if (current->left == nullptr) { node *temp = current->right; delete current; return temp; }
   3891             if (current->right == nullptr) { node *temp = current->left; delete current; return temp; }
   3892             node *pred = current->left;
   3893             while (pred->right != nullptr) pred = pred->right;
   3894             current->data = pred->data;
   3895             current->left = deleteByCopying(current->left, pred->data);
   3896         }
   3897         return current;
   3898     }
   3899 
   3900     node* deleteByMerging(node *current, int key) {
   3901         if (current == nullptr) return nullptr;
   3902         if (key < current->data) { current->left = deleteByMerging(current->left, key); return current; }
   3903         if (key > current->data) { current->right = deleteByMerging(current->right, key); return current; }
   3904         if (current->left == nullptr) { node *temp = current->right; delete current; return temp; }
   3905         if (current->right == nullptr) { node *temp = current->left; delete current; return temp; }
   3906         node *successor = current->right;
   3907         while (successor->left != nullptr) successor = successor->left;
   3908         successor->left = current->left;
   3909         node *temp = current->right;
   3910         delete current;
   3911         return temp;
   3912     }
   3913 
   3914     int countLeaf(node *current) {
   3915         if (current == nullptr) return 0;
   3916         if (current->left == nullptr && current->right == nullptr) return 1;
   3917         return countLeaf(current->left) + countLeaf(current->right);
   3918     }
   3919 
   3920     int countNonLeaf(node *current) {
   3921         if (current == nullptr) return 0;
   3922         if (current->left == nullptr && current->right == nullptr) return 0;
   3923         return 1 + countNonLeaf(current->left) + countNonLeaf(current->right);
   3924     }
   3925 
   3926     int height(node *current) {
   3927         if (current == nullptr) return -1;
   3928         return 1 + max(height(current->left), height(current->right));
   3929     }
   3930 
   3931     void mirror(node *current) {
   3932         if (current == nullptr) return;
   3933         node *temp = current->left;
   3934         current->left = current->right;
   3935         current->right = temp;
   3936         mirror(current->left);
   3937         mirror(current->right);
   3938     }
   3939 
   3940     bool areEqual(node *root1, node *root2) {
   3941         if (root1 == nullptr && root2 == nullptr) return true;
   3942         if (root1 == nullptr || root2 == nullptr) return false;
   3943         if (root1->data != root2->data) return false;
   3944         return areEqual(root1->left, root2->left) && areEqual(root1->right, root2->right);
   3945     }
   3946 
   3947     void destroy(node *current) {
   3948         if (current == nullptr) return;
   3949         destroy(current->left);
   3950         destroy(current->right);
   3951         delete current;
   3952     }
   3953 
   3954 public:
   3955     BST() { root = nullptr; }
   3956 
   3957     void insertRecursive(int val) {
   3958         bool inserted = false;
   3959         root = insertRecursive(root, val, inserted);
   3960     }
   3961 
   3962     void insertIterative(int val) {
   3963         node *newNode = new node(val);
   3964         if (root == nullptr) { root = newNode; return; }
   3965         node *current = root;
   3966         node *parent = nullptr;
   3967         while (current != nullptr) {
   3968             parent = current;
   3969             if (val < current->data) current = current->left;
   3970             else if (val > current->data) current = current->right;
   3971             else { cout << "Duplicate value ignored.\n"; delete newNode; return; }
   3972         }
   3973         if (val < parent->data) parent->left = newNode;
   3974         else parent->right = newNode;
   3975     }
   3976 
   3977     void deleteCopying(int key) {
   3978         if (!search(key)) { cout << "Element not found in BST.\n"; return; }
   3979         root = deleteByCopying(root, key);
   3980     }
   3981 
   3982     void deleteMerging(int key) {
   3983         if (!search(key)) { cout << "Element not found in BST.\n"; return; }
   3984         root = deleteByMerging(root, key);
   3985     }
   3986 
   3987     bool search(int key) {
   3988         node *current = root;
   3989         while (current != nullptr) {
   3990             if (current->data == key) return true;
   3991             current = (key < current->data) ? current->left : current->right;
   3992         }
   3993         return false;
   3994     }
   3995 
   3996     void preorderRecursive() { preorderRecursive(root); cout << endl; }
   3997     void inorderRecursive() { inorderRecursive(root); cout << endl; }
   3998     void postorderRecursive() { postorderRecursive(root); cout << endl; }
   3999 
   4000     void preorderIterative() {
   4001         if (root == nullptr) return;
   4002         stack<node*> s;
   4003         s.push(root);
   4004         while (!s.empty()) {
   4005             node *current = s.top(); s.pop();
   4006             cout << current->data << " ";
   4007             if (current->right != nullptr) s.push(current->right);
   4008             if (current->left != nullptr) s.push(current->left);
   4009         }
   4010         cout << endl;
   4011     }
   4012 
   4013     void inorderIterative() {
   4014         stack<node*> s;
   4015         node *current = root;
   4016         while (current != nullptr || !s.empty()) {
   4017             while (current != nullptr) { s.push(current); current = current->left; }
   4018             current = s.top(); s.pop();
   4019             cout << current->data << " ";
   4020             current = current->right;
   4021         }
   4022         cout << endl;
   4023     }
   4024 
   4025     void postorderIterative() {
   4026         if (root == nullptr) return;
   4027         stack<node*> s1, s2;
   4028         s1.push(root);
   4029         while (!s1.empty()) {
   4030             node *current = s1.top(); s1.pop();
   4031             s2.push(current);
   4032             if (current->left != nullptr) s1.push(current->left);
   4033             if (current->right != nullptr) s1.push(current->right);
   4034         }
   4035         while (!s2.empty()) { cout << s2.top()->data << " "; s2.pop(); }
   4036         cout << endl;
   4037     }
   4038 
   4039     void levelOrder() {
   4040         if (root == nullptr) return;
   4041         queue<node*> q;
   4042         q.push(root);
   4043         while (!q.empty()) {
   4044             node *current = q.front(); q.pop();
   4045             cout << current->data << " ";
   4046             if (current->left != nullptr) q.push(current->left);
   4047             if (current->right != nullptr) q.push(current->right);
   4048         }
   4049         cout << endl;
   4050     }
   4051 
   4052     void countNodes() {
   4053         cout << "Leaf Nodes: " << countLeaf(root) << endl;
   4054         cout << "Non-Leaf Nodes: " << countNonLeaf(root) << endl;
   4055     }
   4056 
   4057     void displayHeight() { cout << "Height of Tree: " << height(root) << endl; }
   4058 
   4059     void createMirror() { mirror(root); }
   4060 
   4061     bool isEqual(BST &other) { return areEqual(root, other.root); }
   4062 
   4063     ~BST() { destroy(root); }
   4064 };
   4065 
   4066 int main() {
   4067     BST tree;
   4068     int choice, value;
   4069 
   4070     while (true) {
   4071         cout << "1.InsertRec 2.InsertIter 3.DeleteCopy 4.DeleteMerge 5.Search\n";
   4072         cout << "6.PreorderRec 7.InorderRec 8.PostorderRec 9.PreorderIter 10.InorderIter\n";
   4073         cout << "11.PostorderIter 12.LevelOrder 13.CountNodes 14.Height 15.Mirror 16.CheckEqual 0.Exit\n";
   4074         cout << "Enter your choice: ";
   4075         cin >> choice;
   4076 
   4077         switch (choice) {
   4078             case 1: cout << "Enter value: "; cin >> value; tree.insertRecursive(value); break;
   4079             case 2: cout << "Enter value: "; cin >> value; tree.insertIterative(value); break;
   4080             case 3: cout << "Enter value to delete: "; cin >> value; tree.deleteCopying(value); break;
   4081             case 4: cout << "Enter value to delete: "; cin >> value; tree.deleteMerging(value); break;
   4082             case 5:
   4083                 cout << "Enter value to search: "; cin >> value;
   4084                 cout << (tree.search(value) ? "Found\n" : "Not found\n");
   4085                 break;
   4086             case 6: tree.preorderRecursive(); break;
   4087             case 7: tree.inorderRecursive(); break;
   4088             case 8: tree.postorderRecursive(); break;
   4089             case 9: tree.preorderIterative(); break;
   4090             case 10: tree.inorderIterative(); break;
   4091             case 11: tree.postorderIterative(); break;
   4092             case 12: tree.levelOrder(); break;
   4093             case 13: tree.countNodes(); break;
   4094             case 14: tree.displayHeight(); break;
   4095             case 15: tree.createMirror(); break;
   4096             case 16: {
   4097                 BST tree2;
   4098                 int n;
   4099                 cout << "Enter number of nodes for second BST: "; cin >> n;
   4100                 for (int i = 0; i < n; i++) { cin >> value; tree2.insertIterative(value); }
   4101                 cout << (tree.isEqual(tree2) ? "Both BSTs are equal.\n" : "BSTs are not equal.\n");
   4102                 break;
   4103             }
   4104             case 0: return 0;
   4105             default: cout << "Wrong choice.\n";
   4106         }
   4107     }
   4108 }
   4109 ```
   4110 ///
   4111 ### Output:
   4112 ![[Pasted image 20260923202214.png|691]]
   4113 <p align="right">Continue to next page...</p>
   4114 ///
   4115 ![[Pasted image 20260923202219.png|694]]
   4116 <p align="right">Continue to next page...</p>
   4117 ///
   4118 ![[Pasted image 20260923202226.png|697]]
   4119 ///
   4120 ### Discussion:
   4121 - **insertRecursive()** recursively finds the correct NULL position by comparing with each node's data and attaches the new node there.
   4122 - **insertIterative()** walks down the tree using a `current`/`parent` pointer pair until it finds the correct empty spot, then links the new node.
   4123 - **search()** iteratively compares the key against each node's data, moving left or right until found or the tree is exhausted.
   4124 - **deleteByCopying()** locates the node, then replaces its data with the inorder predecessor's data and recursively deletes that predecessor.
   4125 - **deleteByMerging()** locates the node and, if it has two children, attaches its left subtree under the leftmost node of its right subtree, then removes the node.
   4126 - **preorderRecursive() / inorderRecursive() / postorderRecursive()** visit root-left-right, left-root-right, and left-right-root respectively using recursive calls.
   4127 - **preorderIterative()** uses a stack, pushing right then left children so left is processed first.
   4128 - **inorderIterative()** pushes left children onto a stack until NULL, then pops, prints, and moves right.
   4129 - **postorderIterative()** uses two stacks: the first collects nodes in a modified preorder, the second reverses that order for postorder output.
   4130 - **levelOrder()** uses a queue to visit nodes breadth-first, enqueuing children as each node is dequeued.
   4131 - **countLeaf() / countNonLeaf()** recursively count nodes with no children versus nodes with at least one child.
   4132 - **height()** recursively computes `1 + max(leftHeight, rightHeight)`, with an empty tree returning -1.
   4133 - **mirror()** recursively swaps the left and right children of every node.
   4134 - **areEqual()** recursively compares two trees node by node, checking both structure and data.
   4135 
   4136 ///
   4137 ## Assignment 17
   4138 ### Problem Statement:
   4139 WAP to convert the Sparse Matrix into non-zero form and vice-versa.
   4140 ### Problem Defination:
   4141 A **Sparse Matrix** is a matrix in which most elements are zero. Storing it in standard 2D form wastes memory, so it is instead represented in **3-tuple (triplet) form**, storing only the row, column, and value of each non-zero element, along with the matrix's total rows, columns, and non-zero count in the first row.
   4142 ### Algorithm:
   4143 **Convert Standard 2D Matrix to 3-Tuple Representation:**
   4144 ```
   4145 procedure convertToTriplet(matrix, rows, cols)
   4146 begin
   4147 	count ← 0;
   4148 	for i ← 0 to rows - 1 do
   4149 		for j ← 0 to cols - 1 do
   4150 			if(matrix[i][j] ≠ 0)
   4151 				count ← count + 1;
   4152 			end if
   4153 		end for
   4154 	end for
   4155 
   4156 	allocate triplet of size (count + 1) x 3;
   4157 	triplet[0][0] ← rows;
   4158 	triplet[0][1] ← cols;
   4159 	triplet[0][2] ← count;
   4160 
   4161 	k ← 1;
   4162 	for i ← 0 to rows - 1 do
   4163 		for j ← 0 to cols - 1 do
   4164 			if(matrix[i][j] ≠ 0)
   4165 				triplet[k][0] ← i;
   4166 				triplet[k][1] ← j;
   4167 				triplet[k][2] ← matrix[i][j];
   4168 				k ← k + 1;
   4169 			end if
   4170 		end for
   4171 	end for
   4172 end procedure
   4173 ```
   4174 
   4175 **Convert 3-Tuple Representation to Standard 2D Matrix:**
   4176 ```
   4177 procedure convertToStandard(triplet)
   4178 begin
   4179 	rows ← triplet[0][0];
   4180 	cols ← triplet[0][1];
   4181 	count ← triplet[0][2];
   4182 
   4183 	allocate matrix of size rows x cols;
   4184 	for i ← 0 to rows - 1 do
   4185 		for j ← 0 to cols - 1 do
   4186 			matrix[i][j] ← 0;
   4187 		end for
   4188 	end for
   4189 
   4190 	for i ← 1 to count do
   4191 		r ← triplet[i][0];
   4192 		c ← triplet[i][1];
   4193 		val ← triplet[i][2];
   4194 		if(r >= 0 and r < rows and c >= 0 and c < cols)
   4195 			matrix[r][c] ← val;
   4196 		end if
   4197 	end for
   4198 end procedure
   4199 ```
   4200 
   4201 ### Source Code:
   4202 ```
   4203 #include <iostream>
   4204 using namespace std;
   4205 
   4206 class SparseMatrix {
   4207 private:
   4208     int rows;
   4209     int cols;
   4210     int **standardMatrix;
   4211     int **triplet;
   4212     int nonZeroCount;
   4213 
   4214     void allocateStandard(int r, int c) {
   4215         rows = r;
   4216         cols = c;
   4217         standardMatrix = new int*[rows];
   4218         for (int i = 0; i < rows; i++) {
   4219             standardMatrix[i] = new int[cols];
   4220             for (int j = 0; j < cols; j++) standardMatrix[i][j] = 0;
   4221         }
   4222     }
   4223 
   4224     void freeStandard() {
   4225         if (standardMatrix != nullptr) {
   4226             for (int i = 0; i < rows; i++) delete[] standardMatrix[i];
   4227             delete[] standardMatrix;
   4228             standardMatrix = nullptr;
   4229         }
   4230     }
   4231 
   4232     void freeTriplet() {
   4233         if (triplet != nullptr) {
   4234             for (int i = 0; i <= nonZeroCount; i++) delete[] triplet[i];
   4235             delete[] triplet;
   4236             triplet = nullptr;
   4237         }
   4238     }
   4239 
   4240 public:
   4241     SparseMatrix() {
   4242         rows = 0; cols = 0; nonZeroCount = 0;
   4243         standardMatrix = nullptr;
   4244         triplet = nullptr;
   4245     }
   4246 
   4247     void inputStandardMatrix() {
   4248         freeStandard();
   4249         freeTriplet();
   4250         cout << "Enter number of rows: "; cin >> rows;
   4251         cout << "Enter number of columns: "; cin >> cols;
   4252         if (rows <= 0 || cols <= 0) { cout << "Invalid matrix dimensions!\n"; rows = cols = 0; return; }
   4253         allocateStandard(rows, cols);
   4254         cout << "Enter matrix elements (" << rows << " x " << cols << "):\n";
   4255         for (int i = 0; i < rows; i++)
   4256             for (int j = 0; j < cols; j++) cin >> standardMatrix[i][j];
   4257     }
   4258 
   4259     void convertToTriplet() {
   4260         if (standardMatrix == nullptr) { cout << "No standard matrix available!\n"; return; }
   4261         freeTriplet();
   4262         nonZeroCount = 0;
   4263         for (int i = 0; i < rows; i++)
   4264             for (int j = 0; j < cols; j++)
   4265                 if (standardMatrix[i][j] != 0) nonZeroCount++;
   4266 
   4267         triplet = new int*[nonZeroCount + 1];
   4268         for (int i = 0; i <= nonZeroCount; i++) triplet[i] = new int[3];
   4269 
   4270         triplet[0][0] = rows;
   4271         triplet[0][1] = cols;
   4272         triplet[0][2] = nonZeroCount;
   4273 
   4274         int k = 1;
   4275         for (int i = 0; i < rows; i++)
   4276             for (int j = 0; j < cols; j++)
   4277                 if (standardMatrix[i][j] != 0) {
   4278                     triplet[k][0] = i;
   4279                     triplet[k][1] = j;
   4280                     triplet[k][2] = standardMatrix[i][j];
   4281                     k++;
   4282                 }
   4283     }
   4284 
   4285     void inputTripletForm() {
   4286         freeStandard();
   4287         freeTriplet();
   4288         int r, c, count;
   4289         cout << "Enter total rows: "; cin >> r;
   4290         cout << "Enter total columns: "; cin >> c;
   4291         cout << "Enter number of non-zero elements: "; cin >> count;
   4292         if (r <= 0 || c <= 0 || count < 0 || count > r * c) { cout << "Invalid input parameters!\n"; return; }
   4293 
   4294         rows = r; cols = c; nonZeroCount = count;
   4295         triplet = new int*[nonZeroCount + 1];
   4296         for (int i = 0; i <= nonZeroCount; i++) triplet[i] = new int[3];
   4297 
   4298         triplet[0][0] = rows;
   4299         triplet[0][1] = cols;
   4300         triplet[0][2] = nonZeroCount;
   4301 
   4302         cout << "Enter (row, col, value) for each non-zero element:\n";
   4303         for (int i = 1; i <= nonZeroCount; i++) cin >> triplet[i][0] >> triplet[i][1] >> triplet[i][2];
   4304     }
   4305 
   4306     void convertToStandard() {
   4307         if (triplet == nullptr) { cout << "No 3-tuple representation found!\n"; return; }
   4308         freeStandard();
   4309         rows = triplet[0][0];
   4310         cols = triplet[0][1];
   4311         nonZeroCount = triplet[0][2];
   4312         allocateStandard(rows, cols);
   4313 
   4314         for (int i = 1; i <= nonZeroCount; i++) {
   4315             int r = triplet[i][0];
   4316             int c = triplet[i][1];
   4317             int val = triplet[i][2];
   4318             if (r >= 0 && r < rows && c >= 0 && c < cols) standardMatrix[r][c] = val;
   4319         }
   4320     }
   4321 
   4322     void displayStandard() {
   4323         if (standardMatrix == nullptr) { cout << "Standard matrix is empty!\n"; return; }
   4324         for (int i = 0; i < rows; i++) {
   4325             for (int j = 0; j < cols; j++) cout << standardMatrix[i][j] << " ";
   4326             cout << endl;
   4327         }
   4328     }
   4329 
   4330     void displayTriplet() {
   4331         if (triplet == nullptr) { cout << "3-Tuple representation is empty!\n"; return; }
   4332         for (int i = 0; i <= nonZeroCount; i++)
   4333             cout << triplet[i][0] << " " << triplet[i][1] << " " << triplet[i][2] << endl;
   4334     }
   4335 
   4336     ~SparseMatrix() {
   4337         freeStandard();
   4338         freeTriplet();
   4339     }
   4340 };
   4341 
   4342 int main() {
   4343     SparseMatrix sm;
   4344     int choice;
   4345 
   4346     while (true) {
   4347         cout << "1.InputMatrix 2.ToTriplet 3.DisplayTriplet \n4.InputTriplet 5.ToStandard 6.DisplayMatrix -1.Exit\n";
   4348         cout << "Enter your choice: ";
   4349         cin >> choice;
   4350 
   4351         switch (choice) {
   4352             case 1: sm.inputStandardMatrix(); break;
   4353             case 2: sm.convertToTriplet(); break;
   4354             case 3: sm.displayTriplet(); break;
   4355             case 4: sm.inputTripletForm(); break;
   4356             case 5: sm.convertToStandard(); break;
   4357             case 6: sm.displayStandard(); break;
   4358             case -1: cout << "Exiting...\n"; return 0;
   4359             default: cout << "Wrong choice.\n";
   4360         }
   4361     }
   4362 }
   4363 ```
   4364 ///
   4365 ### Output:
   4366 ![[Pasted image 20260923203309.png|384]]
   4367 ![[Pasted image 20260923203343.png|380]]
   4368 ### Discussion:
   4369 - **convertToTriplet()** scans the 2D matrix to count non-zero elements, allocates a triplet array of that size, and fills it with the row, column, and value of each non-zero entry, with row 0 storing the matrix dimensions and non-zero count.
   4370 - **convertToStandard()** reads the dimensions and count from row 0 of the triplet array, allocates a zero-filled 2D matrix, and places each stored value at its recorded row and column.
   4371 
   4372 ///
   4373 ## Assignment 18
   4374 ### Problem Statement:
   4375 WAP to reverse the order of the elements in the stack using additional stack.
   4376 ### Problem Defination:
   4377 Reversing a **Stack** means making the bottom element the new top and vice versa. This can be achieved using two **auxiliary stacks**: elements are popped off the original stack and pushed twice across two helper stacks, which reverses the order twice and restores the elements to the original stack in reversed order.
   4378 
   4379 ### Algorithm:
   4380 **Reverse Stack Using Additional Stacks:**
   4381 ```
   4382 procedure reverseUsingAdditionalStacks(S, capacity)
   4383 begin
   4384 	if(isEmpty(S))
   4385 		print "Stack is empty! Nothing to reverse.";
   4386 		return;
   4387 	end if
   4388 
   4389 	initialize stack S1 of capacity;
   4390 	initialize stack S2 of capacity;
   4391 
   4392 	while(not isEmpty(S)) do
   4393 		val ← pop(S);
   4394 		push(S1, val);
   4395 	end while
   4396 
   4397 	while(not isEmpty(S1)) do
   4398 		val ← pop(S1);
   4399 		push(S2, val);
   4400 	end while
   4401 
   4402 	while(not isEmpty(S2)) do
   4403 		val ← pop(S2);
   4404 		push(S, val);
   4405 	end while
   4406 end procedure
   4407 ```
   4408 
   4409 ### Source Code:
   4410 ```
   4411 #include <iostream>
   4412 using namespace std;
   4413 
   4414 class Stack {
   4415 private:
   4416     int *arr;
   4417     int top;
   4418     int capacity;
   4419 
   4420 public:
   4421     Stack(int size) {
   4422         capacity = size;
   4423         arr = new int[capacity];
   4424         top = -1;
   4425     }
   4426 
   4427     Stack(const Stack&) = delete;
   4428     Stack& operator=(const Stack&) = delete;
   4429 
   4430     bool isFull() const { return (top == capacity - 1); }
   4431     bool isEmpty() const { return (top == -1); }
   4432 
   4433     void push(int val) {
   4434         if (isFull()) { cout << "Stack Overflow!\n"; return; }
   4435         arr[++top] = val;
   4436     }
   4437 
   4438     int pop() {
   4439         if (isEmpty()) { cout << "Stack Underflow!\n"; return -1; }
   4440         return arr[top--];
   4441     }
   4442 
   4443     void display() const {
   4444         if (isEmpty()) { cout << "Stack is empty!\n"; return; }
   4445         for (int i = top; i >= 0; i--) cout << arr[i] << " ";
   4446         cout << endl;
   4447     }
   4448 
   4449     void reverseUsingAdditionalStacks() {
   4450         if (isEmpty()) { cout << "Stack is empty! Nothing to reverse.\n"; return; }
   4451 
   4452         Stack s1(capacity);
   4453         Stack s2(capacity);
   4454 
   4455         while (!isEmpty()) s1.push(pop());
   4456         while (!s1.isEmpty()) s2.push(s1.pop());
   4457         while (!s2.isEmpty()) push(s2.pop());
   4458     }
   4459 
   4460     ~Stack() { delete[] arr; }
   4461 };
   4462 
   4463 int main() {
   4464     int size, choice, val;
   4465     cout << "Enter the capacity of the stack: ";
   4466     cin >> size;
   4467     if (size <= 0) { cout << "Invalid stack size!\n"; return 0; }
   4468 
   4469     Stack s(size);
   4470 
   4471     while (true) {
   4472         cout << "1.push 2.pop 3.reverse 0.display -1.Exit\n";
   4473         cout << "Enter your choice: ";
   4474         cin >> choice;
   4475 
   4476         switch (choice) {
   4477             case 1:
   4478                 cout << "Enter value: ";
   4479                 cin >> val;
   4480                 s.push(val);
   4481                 break;
   4482             case 2: {
   4483                 int v = s.pop();
   4484                 if (v != -1) cout << "Popped element: " << v << endl;
   4485                 break;
   4486             }
   4487             case 3:
   4488                 s.reverseUsingAdditionalStacks();
   4489                 cout << "Stack reversed.\n";
   4490                 break;
   4491             case 0:
   4492                 s.display();
   4493                 break;
   4494             case -1:
   4495                 cout << "Exiting...\n";
   4496                 return 0;
   4497             default:
   4498                 cout << "Wrong choice.\n";
   4499         }
   4500     }
   4501 }
   4502 ```
   4503 ///
   4504 ### Output:
   4505 ![[Pasted image 20260923205641.png]]
   4506 
   4507 ### Discussion:
   4508 - **reverseUsingAdditionalStacks()** empties the original stack into `s1` (reversing the order once), then transfers `s1` into `s2` (reversing it again), then pushes `s2`'s elements back into the original stack, leaving it in reversed order.
   4509 
   4510 ///
   4511 ## Assignment 19
   4512 ### Problem Statement:
   4513 WAP to reverse the order of the elements in the stack using additional Queue.
   4514 ### Problem Defination:
   4515 Reversing a **Stack** using an auxiliary **Queue** exploits the FIFO order of a queue: elements popped off the stack (in top-to-bottom order) are enqueued, and dequeuing them back (in the same order they were enqueued) and pushing them onto the stack reverses the original arrangement.
   4516 ### Algorithm:
   4517 **Reverse Stack Using Additional Queue:**
   4518 ```
   4519 procedure reverseUsingQueue(S, capacity)
   4520 begin
   4521 	if(isEmpty(S))
   4522 		print "Stack is empty! Nothing to reverse.";
   4523 		return;
   4524 	end if
   4525 
   4526 	initialize queue Q of capacity;
   4527 
   4528 	while(not isEmpty(S)) do
   4529 		val ← pop(S);
   4530 		enqueue(Q, val);
   4531 	end while
   4532 
   4533 	while(not isEmpty(Q)) do
   4534 		val ← dequeue(Q);
   4535 		push(S, val);
   4536 	end while
   4537 end procedure
   4538 ```
   4539 ### Source Code:
   4540 ```
   4541 #include <iostream>
   4542 using namespace std;
   4543 
   4544 class Queue {
   4545 private:
   4546     int *arr;
   4547     int front;
   4548     int rear;
   4549     int capacity;
   4550 
   4551 public:
   4552     Queue(int size) {
   4553         capacity = size;
   4554         arr = new int[capacity];
   4555         front = -1;
   4556         rear = -1;
   4557     }
   4558 
   4559     bool isEmpty() { return (front == -1 || front > rear); }
   4560     bool isFull() { return (rear == capacity - 1); }
   4561 
   4562     void enqueue(int val) {
   4563         if (isFull()) return;
   4564         if (front == -1) front = 0;
   4565         arr[++rear] = val;
   4566     }
   4567 
   4568     int dequeue() {
   4569         if (isEmpty()) return -1;
   4570         int val = arr[front++];
   4571         if (front > rear) { front = -1; rear = -1; }
   4572         return val;
   4573     }
   4574 
   4575     ~Queue() { delete[] arr; }
   4576 };
   4577 
   4578 class Stack {
   4579 private:
   4580     int *arr;
   4581     int top;
   4582     int capacity;
   4583 
   4584 public:
   4585     Stack(int size) {
   4586         capacity = size;
   4587         arr = new int[capacity];
   4588         top = -1;
   4589     }
   4590 
   4591     bool isFull() { return (top == capacity - 1); }
   4592     bool isEmpty() { return (top == -1); }
   4593 
   4594     void push(int val) {
   4595         if (isFull()) { cout << "Stack Overflow!\n"; return; }
   4596         arr[++top] = val;
   4597     }
   4598 
   4599     int pop() {
   4600         if (isEmpty()) { cout << "Stack Underflow!\n"; return -1; }
   4601         return arr[top--];
   4602     }
   4603 
   4604     void display() {
   4605         if (isEmpty()) { cout << "Stack is empty!\n"; return; }
   4606         for (int i = top; i >= 0; i--) cout << arr[i] << " ";
   4607         cout << endl;
   4608     }
   4609 
   4610     void reverseUsingQueue() {
   4611         if (isEmpty()) { cout << "Stack is empty! Nothing to reverse.\n"; return; }
   4612 
   4613         Queue q(capacity);
   4614         while (!isEmpty()) q.enqueue(pop());
   4615         while (!q.isEmpty()) push(q.dequeue());
   4616     }
   4617 
   4618     ~Stack() { delete[] arr; }
   4619 };
   4620 
   4621 int main() {
   4622     int size, choice, val;
   4623     cout << "Enter the capacity of the stack: ";
   4624     cin >> size;
   4625     if (size <= 0) { cout << "Invalid stack size!\n"; return 0; }
   4626 
   4627     Stack s(size);
   4628 
   4629     while (true) {
   4630         cout << "1.push 2.pop 3.reverse 0.display -1.Exit\n";
   4631         cout << "Enter your choice: ";
   4632         cin >> choice;
   4633 
   4634         switch (choice) {
   4635             case 1:
   4636                 cout << "Enter value: ";
   4637                 cin >> val;
   4638                 s.push(val);
   4639                 break;
   4640             case 2: {
   4641                 int v = s.pop();
   4642                 if (v != -1) cout << "Popped element: " << v << endl;
   4643                 break;
   4644             }
   4645             case 3:
   4646                 s.reverseUsingQueue();
   4647                 break;
   4648             case 0:
   4649                 s.display();
   4650                 break;
   4651             case -1:
   4652                 cout << "Exiting...\n";
   4653                 return 0;
   4654             default:
   4655                 cout << "Wrong choice.\n";
   4656         }
   4657     }
   4658 }
   4659 ```
   4660 
   4661 ### Output:
   4662 ![[Pasted image 20260923205948.png|510]]
   4663 ///
   4664 ### Discussion:
   4665 - **reverseUsingQueue()** dequeues elements from the stack and enqueues them into a queue in top-to-bottom order, then dequeues them from the queue (same order) and pushes them back onto the stack, producing the reversed arrangement.