my_obsidian

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

assignment_updated.md (135930B)


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