75074 Vaishnavi Sharma Analysis of Algorithm and Data Structures 06-05-2022 Practical File Q1.) Implement Insertion Sort and report the number of comparisons. #include <bits/stdc++.h> using namespace std; int insertionSort(int arr[], int n){ int i, key, j, comp=0; for (i=1; i<n; i++){ key = arr[i]; j = i-1; comp++; while (j>=0 && arr[j]>key){ arr[j+1] = arr[j]; j = j-1; comp++; } arr[j+1] = key; } return comp; } // A utility function to print an array of size n void printArray(int arr[], int n) { int i; for (i = 0; i < n; i++) cout << arr[i] << " "; cout << endl; } /* Driver code */ int main() { cout<<"\n"; int arr[] = { 12, 11, 13, 5, 6, 0, 1, 100, 56}; int n = sizeof(arr) / sizeof(arr[0]); cout<<"Original Array\n"; printArray(arr, n); cout<<insertionSort(arr, n)<<" comparisions"<<endl; printArray(arr, n); return 0; } Q2.) Implement Merge Sort and report the number of comparisons. #include <bits/stdc++.h> using namespace std; int comp =0; void merge(int array[], int const left, int const mid, int const right){ int const subArrayOne = mid - left + 1; int const subArrayTwo = right - mid; //creating temp arrays // First subarray is arr[begin..mid] // Second subarray is arr[mid+1..end] auto *leftArray = new int[subArrayOne], *rightArray = new int[subArrayTwo]; // Copy data to temp arrays leftArray[] and rightArray[] for (int i=0; i<subArrayOne; i++){ leftArray[i] = array[left + i]; comp++; } for (int j =0; j < subArrayTwo; j++){ rightArray[j] = array[mid + 1 + j]; comp++; } int indexOfSubArrayOne = 0, // Initial index of first sub-array indexOfSubArrayTwo = 0; // Initial index of second sub-array int k = left; // Initial index of merged array // Merge the temp arrays back into array[left..right] while (indexOfSubArrayOne < subArrayOne && indexOfSubArrayTwo < subArrayTwo){ comp++; if (leftArray[indexOfSubArrayOne] <= rightArray[indexOfSubArrayTwo]) { array[k] = leftArray[indexOfSubArrayOne]; indexOfSubArrayOne++; comp++; } else { array[k] = rightArray[indexOfSubArrayTwo]; indexOfSubArrayTwo++; } k++; } // Copy the remaining elements of // left[], if there are any while (indexOfSubArrayOne < subArrayOne) { comp++; array[k] = leftArray[indexOfSubArrayOne]; indexOfSubArrayOne++; k++; } // Copy the remaining elements of // right[], if there are any while (indexOfSubArrayTwo < subArrayTwo) { comp++; array[k] = rightArray[indexOfSubArrayTwo]; indexOfSubArrayTwo++; k++; } } void mergeSort(int array[], int const begin, int const end){ if (begin >= end){ comp++; return; } int mid = begin + (end - begin) / 2; mergeSort(array, begin, mid); mergeSort(array, mid+1, end); merge(array, begin, mid, end); } void printArray(int A[], int size){ for (int i=0; i<size; i++) cout<<A[i]<<" "; } int main(){ int arr[] = {4, 6, 89, 0, 34, 824, 67}; int arr_size = sizeof(arr)/sizeof(arr[0]); cout<<"Given array is\n"; printArray(arr, arr_size); mergeSort(arr, 0, arr_size - 1); cout<<"\nSorted Array is\n"; printArray(arr, arr_size); cout<<endl<<comp<<" comparisions\n"; return 0; } Q3.) Implement Heap Sort and report the number of comparisons. //heap sort #include <bits/stdc++.h> using namespace std; int comp = 0; void swap(int &x, int &y){ int z = x; x = y; y = z; } void heapify(int arr[], int n, int i){ int largest = i; //Initialize largest as root int l = 2 * i + 1; //left = 2*i + 1 int r = 2 * i + 2; //right = 2*i + 2 // If left child is larger than root if (l < n && arr[l] > arr[largest]){ comp++; largest = l; } // If right child is largest than root if (r < n && arr[r] > arr[largest]){ comp++; largest = r; } // If largest is not root if (largest != i){ comp++; swap(arr[i], arr[largest]); // Recursively heapify the affected sub-tree heapify(arr, n, largest); } } void heapSort(int arr[], int n){ //Build heap (rearrange array) for (int i = n/2 - 1; i >= 0; i--){ comp++; heapify(arr, n, i); } // one by one extract an element from heap for (int i = n-1; i>0; i--){ comp++; //Move current root to end swap(arr[0], arr[i]); // call max heapify on the reduced heap heapify(arr, i, 0); } } void printArray(int arr[], int n){ for(int i=0; i<n; i++) cout<<arr[i]<<" "; cout<<"\n"; } int main(){ int arr[] = {40,72,786,200,1,81,3,45}; int n = sizeof(arr)/sizeof(arr[0]); cout<<"Unsorted array is\n"; printArray(arr, n); heapSort(arr, n); cout<<"Sorted array is\n"; printArray(arr, n); cout<<endl<<comp<<" comparisions"; } Q4.) Implement Randomized Quick sort and report the number of comparisons. // quick sort #include <bits/stdc++.h> using namespace std; int comp = 0; void swap(int* a, int* b) { int t = *a; *a = *b; *b = t; } /* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot */ int partition (int arr[], int low, int high){ int pivot = arr[high]; //pivot int i = (low - 1); // Index of smaller element and indicates the right position of pivot found so far for(int j=low; j <=high-1; j++){ comp++; //If current element is smaller than the pivot if (arr[j] < pivot){ comp++; i++; // increment index of smaller element swap(&arr[i], &arr[j]); } } swap(&arr[i+1], &arr[high]); return (i+1); } //low: starting index //high: ending index void quickSort(int arr[], int low, int high){ if(low < high){ comp++; //pi is partition index, arr[p] is nowat the right place int pi = partition(arr, low, high); quickSort(arr, low, pi-1); quickSort(arr, pi+1, high); } } void printArray(int arr[], int size){ int i; for(i=0; i<size; i++) cout<<arr[i]<<" "; cout<<endl; } int main(){ int arr[] = {12,76,49,1994,390,30,36,43,35,6}; int n = sizeof(arr)/sizeof(arr[0]); cout<<"Given array is\n"; printArray(arr, n); quickSort(arr, 0, n-1); cout<<"\nSorted Array is\n"; printArray(arr, n); cout<<endl<<comp<<" comparisions\n"; printArray(arr, n); return 0; } Q5.) Implement Radix sort. // Radix Sort #include <iostream> using namespace std; // A utility function to get maximum value in arr[] int getMax(int arr[], int n) { int mx = arr[0]; for (int i = 1; i < n; i++) if (arr[i] > mx) mx = arr[i]; return mx; } // A function to do counting sort of arr[] according to // the digit represented by exp. void countSort(int arr[], int n, int exp) { int output[n]; // output array int i, count[10] = { 0 }; // Store count of occurrences in count[] for (i = 0; i < n; i++) count[(arr[i] / exp) % 10]++; // Change count[i] so that count[i] now contains actual // position of this digit in output[] for (i = 1; i < 10; i++) count[i] += count[i - 1]; // Build the output array for (i = n - 1; i >= 0; i--) { output[count[(arr[i] / exp) % 10] - 1] = arr[i]; count[(arr[i] / exp) % 10]--; } // Copy the output array to arr[], so that arr[] now // contains sorted numbers according to current digit for (i = 0; i < n; i++) arr[i] = output[i]; } // The main function to that sorts arr[] of size n using // Radix Sort void radixsort(int arr[], int n) { // Find the maximum number to know number of digits int m = getMax(arr, n); // Do counting sort for every digit. Note that instead // of passing digit number, exp is passed. exp is 10^i // where i is current digit number for (int exp = 1; m / exp > 0; exp *= 10) countSort(arr, n, exp); } // A utility function to print an array void printArray(int arr[], int n) { for (int i = 0; i < n; i++) cout << arr[i] << " "; } // Driver Code int main() { int arr[] = { 170, 45, 75, 90, 802, 24, 2, 66 }; int n = sizeof(arr) / sizeof(arr[0]); cout<<"Given array is\n"; printArray(arr, n); radixsort(arr, n); cout<<"\nSorted Array is\n"; printArray(arr, n); return 0; } Q6.) Implement Searching Techniques. Linear Search #include <iostream> using namespace std; int linear_search(int array[], int n, int x){ int i; for (i = 0; i < n; i++) cout<<"\nloop"<<i<<"\n"; if (array[i] == x) return (i); return(-1); } int main(void){ int array[30], x, n, pos; cout<<"Enter the size of array: "; cin>>n; cout<<"\nEnter array\n"; for(int i = 0; i < n; i++){ cin>>array[i]; } cout<<"enter x: "; cin>>x; pos = linear_search(array, n, x); cout<<pos<<endl; (pos == -1) ? cout<<"Element not found" : cout<<"Element at position: "<<pos+1; return(0); } Binary Search #include <bits/stdc++.h> using namespace std; int binary_search(int arr[], int n, int x){ int beg = 0; int end = n-1; while(beg <= end){ int mid = ((beg + end)/2); if (arr[mid] == x){ return mid;} else if (x > arr[mid]){ beg = mid + 1;} else if (x < arr[mid]){ cout<<""; end = mid - 1;} } return (-1); } int main (void){ int array[30], x, n, pos; cout<<"Enter the size of array: "; cin>>n; cout<<"\nEnter sorted array\n"; for(int i = 0; i < n; i++){ cin>>array[i]; } cout<<"enter x: "; cin>>x; pos = binary_search(array, n, x); cout<<pos<<endl; (pos == -1) ? cout<<"Element not found" : cout<<"Element at position: "<<pos+1; return(0); } Q7.) Implementation of Recursive function. #include <bits/stdc++.h> using namespace std; // A recursive binary search function. It returns // location of x in given array arr[l..r] is present, // otherwise -1 int binarySearch(int arr[], int l, int r, int x) { if (r >= l) { int mid = l + (r - l) / 2; // If the element is present at the middle // itself if (arr[mid] == x) return mid; // If element is smaller than mid, then // it can only be present in left subarray if (arr[mid] > x) return binarySearch(arr, l, mid - 1, x); // Else the element can only be present // in right subarray return binarySearch(arr, mid + 1, r, x); } // We reach here when element is not // present in array return -1; } int main(void) { int arr[] = { 2, 3, 4, 10, 40 }; int x = 10; int n = sizeof(arr) / sizeof(arr[0]); int result = binarySearch(arr, 0, n - 1, x); (result == -1) ? cout << "Element is not present in array" : cout << "Element is present at index " << result; return 0; } Q8.) Array and Linked list implementation of Stack and Queue. Stack implementation using array. // array implementation of stack #include <iostream> using namespace std; int stack[100], n=100, top=-1; void push(int val){ if(top >= n-1) cout<<"Stack Overflow"<<endl; else{ top++; stack[top]=val; } } void pop(){ if(top <=-1) cout<<"Stack Underflow"<<endl; else{ cout<<"The popped element is "<<stack[top]<<endl; top--; } } void display(){ if(top>=0){ cout<<"Stack element are: "; for(int i=top; i>=0; i--) cout<<stack[i]<<" "; cout<<endl; } else cout<<"Stack is empty"; } int main(){ int ch, val; cout<<"1) Push in stack"<<endl; cout<<"2) Pop from stack"<<endl; cout<<"3) Display stack"<<endl; cout<<"4) Exit"<<endl; do{ cout<<"Enter choice: "<<endl; cin>>ch; switch(ch){ case 1:{ cout<<"Enter value to be pushed:"<<endl; cin>>val; push(val); break; } case 2:{ pop(); break; } case 3:{ display(); break; } case 4:{ cout<<"Exit"<<endl; break; } default:{ cout<<"Invalid Choice"<<endl; } } } while(ch!=4); return 0; } Stack implementation using linked lists. #include<iostream> #include<conio.h> #define Size 10 int count=0; using namespace std; class Node{ public: int data; Node * next; }; class Stack{ public: Node * top; bool isEmpty(){ if (top == NULL){ return true; } else{ return false; } } bool isFull(){ if(count==Size) return true; else return false; } void push(Node * n){ if(isFull()){ cout<<"Overflow"; return ; } else if(top == NULL){ top = n; } else{ Node * temp = top; top = n; n -> next = temp; count++; } } Node * pop(){ Node * temp; if (isEmpty()){ cout << "stack underflow" << endl; return temp; } else{ temp = top; top = top -> next; cout<<"Popped element is "<<temp->data<<endl; count--; delete(temp); return top; } } Node * peek(){ if (isEmpty()) { cout << "Stack underflow" << endl; return NULL; } else{ return top; } } void display(){ if(isEmpty()){ cout<<"Underflow Occured !!"<<endl; } else{ cout <<"All values in the Stack are :" << endl; Node * temp = top; while (temp != NULL){ cout <<temp -> data << " " ; temp = temp -> next; } } cout<<endl; } }; int main(){ Stack s1; int option, data; cout<<"1. Push() 2. Pop() 3. isEmpty() 4.isFull() 5.Peek() 6. display()"<<endl; do{ cout <<"Enter Your Choice : "; cin>>option; Node * new_node = new Node(); switch (option) { case 1: cout << "Enter the number to be pushed into stack : "; cin >> data; new_node -> data = data; s1.push(new_node); break; case 2: s1.pop(); break; case 3: if(s1.isEmpty()) cout << "Stack is Empty" << endl; else cout << "Stack is not Empty" << endl; break; case 4: if(s1.isFull()) cout<<"Stack is fulled - Overflow "<<endl; else cout<<"Stack is not fulled "<<endl; break; case 5: if(s1.isEmpty()) { cout << "Stack is Empty " << endl; }