DAA 1 Merged
DAA 1 Merged
Experiment 1
Student Name:                                       UID:
Branch: CSE                                         Section/Group:
Semester: 5th                                       Date of Performance:
Subject Name: DAA LAB                               Subject Code: 22CSH-311
     1. Aim: Analyze if the stack is empty or full, and if elements are present,
         return the top element in the stack using templates. Also, perform push and
         pop operations on the stack.
     2. Objective:
         The objective of this experiment seems to be to implement a stack data
         structure using templates in C++ that supports basic operations such as
         push, pop, top, and checking if the stack is empty or full
         Perform and verify stack operations such as pushing, popping, checking if
         the stack is empty, and accessing the top element.
     3. Implementation/Code:
#include <iostream>
#include <climits>
using namespace std;
template <typename T>
class Stack {
  T* arr;
  int top;
  int capacity;
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
public:
  Stack(int c) {
      capacity = c;
      arr = new T[c];
      top = -1;
  }
  T pop() {
      if (isEmpty()) {
          cout << "Underflow" << endl;
          return T();
      }
      T popped = arr[top];
      top--;
      return popped;
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
     }
     T gettop() {
         if (isEmpty()) {
             cout << "Stack is empty" << endl;
             return T();
         }
         return arr[top];
     }
     bool isEmpty() {
         return top == -1;
     }
     bool isFull() {
         return top == capacity - 1;
     }
};
int main() {
     Stack<int> st(5);
     st.push(8);
     st.push(7);
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
    st.push(10);
    cout << "Top element: " << st.gettop() << endl;
    st.push(2);
    cout << "Top element after push: " << st.gettop() << endl;
    st.pop();
    cout << "Top element after pop: " << st.gettop() << endl
    return 0;
}
4. Output
       5. Time Complexity
          1. Push Operation: O(1)
          2. Pop Operation: O(1)
          3. If empty Operation: O(1)
          4. If full: O(1)
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
    6. Learning Outcome
  • Understanding how to implement a generic stack using templates enhances
     your ability to write flexible and reusable code that can work with different
     data types.
  • Learning the fundamental operations (push, pop, getTop, isEmpty, isFull) and
     their implementation in a stack data structure helps reinforce understanding
     of basic data structures and algorithms.
  • Practicing dynamic memory allocation and deallocation (new[] and delete[])
     within the context of a stack class improves proficiency in memory
     management practices in C++.
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
Experiment 2
Student Name:                                    UID:
Branch: CSE                                      Section/Group:
Semester: 5th                                    Date of Performance:
Subject Name: DAA LAB                            Subject Code: 22CSH-311
       int main() {
           long long x = 2;
           long long n = 10;
           long long result = power(x, n);
           cout << x << "^" << n << " = " << result << endl;
           return 0;
       }
    4. Output
    5. Time Complexity
       O(log n)
    6. Learning Outcome
  • You learn a powerful technique for computing powers efficiently.
     Exponentiation by squaring reduces the number of multiplicative operations
     drastically compared to a naive approach that directly multiplies the base x by
     itself n times.
  • You understand the importance of time complexity in algorithm design
  • You develop skills in algorithmic thinking and optimization
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
Experiment 3
     2. Objective: Traverse the input array and increment the frequency of the element
        if the current element and the previous element are the same, otherwise reset the
        frequency and print the element and its frequency.
     3. Algorithm:
        Step 1: Initialize: Set freq to 1, idx to 1, and element to arr[0].
        Step 2: Traverse Array: While idx < n, check if arr[idx] is equal to arr[idx - 1].
        Step 3: Update Frequency: If equal, increment freq; if not, print element and
        freq, then update element to arr[idx] and reset freq to 1.
        Step 4: Increment Index: Always increment idx.
        Step 5: Print Last: After exiting the loop, print the last element and its freq.
     4. Implementation/Code:
           #include <iostream>
           using namespace std;
        int main() {
           cout << "Frequencies in a sorted Array ::-" << endl;
           int arr[] = {5, 5, 10, 10, 10, 20, 30, 30, 40, 40, 40, 50};
           int n = sizeof(arr) / sizeof(arr[0]);
           findFrequencies(arr, n);
           return 0;
            }
5. Output:
   8. Learning Outcomes:
     a. Understand how to calculate element frequencies in a sorted array.
     b. Learn to implement and debug basic array traversal and comparison
        techniques.
     c. Develop skills in handling and printing results for di
                                                            different
                                                               fferent array scenarios.
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
Experiment 3
     1. Aim: Apply the concept of Linked list and write code to Insert and Delete an element
        at the beginning and at end in Doubly and Circular Linked List.
     2. Objective: The objective of this experiment is to implement and demonstrate the basic
        operations—insertion and deletion—at both the beginning and end of Doubly Linked
        Lists and Circular Linked Lists, showcasing how these structures can be efficiently
        managed and manipulated.
     3. Algorithm:
        Algorithm for Doubly Linked List (DLL)
        Insertion at the Beginning:
            1. Create a New Node: Create a new node with the given data.
            2. Check if List is Empty:
                  o If the list is empty, set both head and tail to point to the new node.
                  o Otherwise, proceed to the next step.
            3. Link New Node:
                  o Set the new node’s next to point to the current head.
                  o Set the current head's prev to point to the new node.
            4. Update Head: Set the new node as the head.
            1. Create a New Node: Create a new node with the given data.
            2. Check if List is Empty:
                  o If the list is empty, set both head and tail to point to the new node.
                  o Otherwise, proceed to the next step.
            3. Link New Node:
                  o Set the current tail's next to point to the new node.
                  o Set the new node’s prev to point to the current tail.
            4. Update Tail: Set the new node as the tail.
      1. Create a New Node: Create a new node with the given data.
      2. Check if List is Empty:
            o If the list is empty, set the head to the new node and point next to itself.
            o Otherwise, proceed to the next step.
      3. Find Last Node:
            o Traverse the list to find the last node (node whose next points to head).
      4. Link New Node:
            o Set the new node’s next to the current head.
            o Set the last node’s next to point to the new node.
      5. Update Head: Set the new node as the head.
      1. Create a New Node: Create a new node with the given data.
      2. Check if List is Empty:
            o If the list is empty, set the head to the new node and point next to itself.
            o Otherwise, proceed to the next step.
      3. Find Last Node:
            o Traverse the list to find the last node (node whose next points to head).
      4. Link New Node:
            o Set the last node’s next to the new node.
            o Set the new node’s next to point to head.
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
   Deletion from the Beginning:
   4. Implementation/Code:
      Doubly Linked List:
        #include <iostream>
        using namespace std;
         struct Node {
            int data;
            Node* prev;
            Node* next;
         class DoublyLinkedList {
         public:
            Node* head;
            Node* tail;
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
        DoublyLinkedList() : head(nullptr), tail(nullptr) {}
            void printList() {
              cout << "Current List: ";
              Node* current = head;
              while (current) {
                 cout << current->data << " ";
                 current = current->next;
              }
              cout << endl;
            }
       };
       int main() {
          DoublyLinkedList dll;
            dll.insertAtBeginning(3);
            dll.insertAtEnd(4);
            dll.insertAtBeginning(2);
            dll.insertAtEnd(5);
            dll.printList(); // Output: 2 3 4 5
            dll.deleteFromBeginning();
            dll.printList(); // Output: 3 4 5
            dll.deleteFromEnd();
            dll.printList(); // Output: 3 4
            return 0;
             }
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
      Circular Linked List:
       #include <iostream>
       using namespace std;
       struct Node {
          int data;
          Node* next;
       class CircularLinkedList {
       public:
          Node* head;
CircularLinkedList() : head(nullptr) {}
            void printList() {
              if (!head) {
                 cout << "The list is empty." << endl;
                 return;
              }
              cout << "Current List: ";
              Node* current = head;
              do {
                 cout << current->data << " ";
                 current = current->next;
              } while (current != head);
              cout << endl;
            }
       };
       int main() {
          CircularLinkedList cll;
            cll.insertAtBeginning(3);
            cll.insertAtEnd(4);
            cll.insertAtBeginning(2);
            cll.insertAtEnd(5);
            cll.printList(); // Output: 2 3 4 5
            cll.deleteFromBeginning();
            cll.printList(); // Output: 3 4 5
            cll.deleteFromEnd();
            cll.printList(); // Output: 3 4
            return 0;
             }
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
   5. Output:
      (Doubly Linked List)
   8. Learning Outcomes:
      a. Understand to manage nodes with insertion and deletion at both ends.
      b. Understand time and space complexities.
      c. Understand to apply linked list to solve real world problems.
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
                              Experiment 5
Student Name: Zatch                               UID:
Branch: CSE                                       Section/Group:
Semester: 5th                                     Date of Performance:
Subject Name: DAA LAB                             Subject Code: 22CSH-311
    1. Aim:
      Sort a given set of elements using the Quick sort method and determine the
      time required to sort the elements. Repeat the experiment for different
      values of n, the number of elements in the list to be sorted. The elements
      can be read from a file or can be generated using the random number
      generator.
    2. Objective:
      To sort a list of elements using the Quick sort algorithm and measure the
      time complexity for different list sizes.
    3. Implementation/Code:
      #include <iostream>
      #include <vector>
      #include <cstdlib>
      #include <ctime>
     double measureTime(int n) {
         vector<int> arr(n);
         for (int& num : arr) {
             num = rand() % 10000; // Random numbers
         }
     int main() {
         srand(time(0)); // Seed for random number generation
         int sizes[] = {100, 500, 1000, 5000, 10000}; // Different sizes to test
         for (int n : sizes) {
             double timeTaken = measureTime(n);
             std::cout << "Time taken to sort " << n << " elements: " << timeTaken
     << " seconds" << std::endl;
         }
         return 0;
     }
4. Output
   5. Time Complexity
     Average Case: O(nlogn)
     Worst Case: O(n^2)
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
   6. Learning Outcome
   • Learn the principles and steps involved in the Quick sort algorithm,
      including the partitioning process and recursive sorting. Understand how
      the algorithm sorts an array by dividing it into smaller sub-arrays.
   • Gain insight into the time and space complexity of Quick sort. Learn to
      differentiate between the average-case, worst-case, and best-case scenarios
      and understand the factors influencing Quick sort's performance.
   • Compare Quick sort's efficiency with other sorting algorithms like Merge
      sort, Heap sort, and Bubble sort. Understand the trade-offs between Quick
      sort’s average-case performance and its worst-case behavior.
   • Develop skills in implementing Quick sort in a programming language
      (e.g., C++). Learn about pivot selection strategies and how they affect the
      algorithm’s performance. Gain experience in optimizing and debugging
      sorting algorithms.
   • Learn how to measure and analyze the performance of Quick sort.
      Understand how to use timing functions to evaluate sorting efficiency and
      how different input sizes impact the sorting time. Develop the ability to
      interpret performance results and apply this knowledge to real-world
      scenarios.
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
                              Experiment-6
Student Name: Zatch                             UID:
Branch: CSE                                     Section/Group:
Semester: 5th                                   Date of Performance:
Subject Name: DAA LAB                           Subject Code: 22CSH-311
    1. Aim:
      Develop a program and analyze complexity to implement subset-sum
      problem using Dynamic Programming.
    2. Objective:
      The objective of this program is to determine whether a subset of a given
      set of integers sums to a specified value. This problem is a classic example
      of dynamic programming where we use a table to store intermediate results
      and build the solution incrementally.
    3. Implementation/Code:
      #include <iostream>
      #include <vector>
         if (j == 0) {
            cout << "{ ";
            for (int num : subset) {
               cout << num << " ";
            }
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
if (i == 0) return;
         if (dp[i-1][j]) {
            printSubsets(arr, dp, i-1, j, subset);
         }
         if (!dp[n][sum]) {
            return false;
         }
         vector<int> subset;
         cout << "Subsets with the given sum are:" << endl;
         printSubsets(arr, dp, n, sum, subset);
         return true;
     }
     int main() {
        vector<int> arr = {3, 34, 4, 12, 5, 2};
        int sum = 9;
         if (!subsetSum(arr, sum)) {
            cout << "No subset with the given sum" << endl;
         }
         return 0;
     }
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
4. Output
   5. Time Complexity :
      O(n * sum) + O(2^n)
   6. Learning Outcome
   • Dynamic Programming concepts and how to apply them to solve problems.
   • The Subset Sum Problem and how to determine if a subset with a given sum
      exists within a set.
   • How to analyze the time and space complexity of a dynamic programming
      algorithm.
   • Improved understanding of two-dimensional arrays in C++ and how to use
      them for dynamic programming tables.
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
Experiment 7
3. Algorithm:
   4. Implementation/Code:
        #include <iostream>
        #include <vector>
        using namespace std;
        int main() {
           // Input values
           vector<int> val = {60, 100, 120};
           vector<int> wt = {10, 20, 30};
           int W = 50;
           int n = val.size();
            // Descriptive Output
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
          cout << "---------------------------\n";
          cout << " 0-1 KNAPSACK PROBLEM \n";
          cout << "---------------------------\n\n";
          return 0;
           }
   5. Output:
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
   6. Time Complexity: O(n * W), where n is the number of items and W is the
      capacity of the knapsack. This is because we fill the DP table of size n × W.
       Space Complexity: O(n * W) for the DP table.
   7. Learning Outcomes:
       Dynamic Programming Concept: Learned how to optimize the 0-1
      Knapsack problem using dynamic programming to reduce time complexity.
       Table-based Approach: Understood the use of a 2D table to store
      intermediate results and build the solution bottom-up.
       Code Presentation: Gained insights into making program output more
      readable and professional through structured formatting.
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
Experiment 8
3. Algorithm:
Step1:- Initialize:
               Create a distance array dist[] and set all values to infinity (∞) except for
                the source node, which is set to 0.
               Use a priority queue (min-heap) to store nodes with their current known
                shortest distance.
 Insert the source node into the priority queue with a distance of 0.
               Extract the node u with the minimum distance from the priority queue.
               For each neighboring node v of u, calculate the tentative distance to v
                through u.
               If this distance is smaller than the current distance in dist[v], update
                dist[v] and insert v into the priority queue with the new distance.
   4. Implementation/Code:
     #include <iostream>
     #include <vector>
     #include <queue>
     #include <climits>
         while (!pq.empty()) {
           int u = pq.top().second; // Get the vertex with the smallest distance
           pq.pop();
                  // Relaxation step
                  if (dist[u] + weight < dist[v]) {
                     dist[v] = dist[u] + weight;
                     pq.push({dist[v], v}); // Push updated distance to the priority queue
                  }
              }
         }
       return 0;
        }
   5. Output:
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
   6. Time Complexity:
     Using Binary Heap: O((V + E) log V), where V is the number of vertices and E
     is the number of edges.
     Using Fibonacci Heap: O(E + V log V).
     Space Complexity:
     The overall space complexity of Dijkstra’s algorithm is O(V + E), where V is
     the number of vertices and E is the number of edges.
   7. Learning Outcomes:
     1. Understanding of Dijkstra's Algorithm: You will learn how to implement
        and apply Dijkstra’s algorithm to find the shortest paths in graphs with
        positive edge weights, utilizing a priority queue for efficiency.
     2. Time and Space Complexity Analysis: You will gain insights into
        analyzing the time complexity (O((V + E) log V) using a binary heap) and
        space complexity (O(V + E)) of the algorithm.
     3. Graph Representation: You will understand how to represent graphs
        efficiently using adjacency lists and handle shortest path problems with real-
        world applications.
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
Experiment 9
     3. Algorithm:
     Step 1: Build LPS Array (Longest Prefix Suffix)
           If j reaches the length of P (i.e., j == m), a full pattern match is found. Record
            the index i - j as the occurrence.
           Then, reset j = lps[j-1] to continue searching.
         while (i < m) {
            if (P[i] == P[len]) {
               len++;
               lps[i] = len;
               i++;
            } else {
               if (len != 0) {
                  len = lps[len - 1]; // use previous lps
               } else {
                  lps[i] = 0;
                  i++;
               }
            }
         }
         return lps;
     }
         cout << "Searching for pattern: \"" << P << "\" in string: \"" << S << "\"\n";
         cout << "--------------------------------------------\n";
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
         while (i < n) {
           if (P[j] == S[i]) {
              i++;
              j++;
           }
             if (j == m) {
                found = true;
                cout << ">> Pattern found at index: " << (i - j) << " <<\n";
                j = lps[j - 1]; // get the index from LPS array
             } else if (i < n && P[j] != S[i]) {
                if (j != 0) {
                   j = lps[j - 1]; // use the LPS array
                } else {
                   i++;
                }
             }
         }
         if (!found) {
            cout << ">> No occurrences of the pattern found. <<\n";
         }
     int main() {
        string S = "ababcababcababc";
        string P = "ababc";
        KMPsearch(S, P);
        return 0;
         }
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
   5. Output:
   7. Learning Outcomes:
      1. Efficient String Matching:
         You will understand how the KMP algorithm efficiently finds all occurrences
         of a pattern P in a string S, avoiding redundant comparisons.
      2. LPS Array Utility:
         You will learn how to construct and utilize the Longest Prefix Suffix (LPS)
         array to skip unnecessary comparisons, optimizing the search process.
      3. Time and Space Trade-offs:
         You will gain insight into analyzing algorithms for both time and space
         complexity, understanding why KMP achieves linear time complexity O(n +
         m) with only O(m) space overhead.