DAA 1 Merged
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.