0% found this document useful (0 votes)
18 views5 pages

Name - Sagar de UNIVERSISTY ROLL - 10931121055 Class Roll - 55 Setion A Semester - 6 Year - 3 ACADEMIC YEAR - 2023-24

Uploaded by

kd14072001
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views5 pages

Name - Sagar de UNIVERSISTY ROLL - 10931121055 Class Roll - 55 Setion A Semester - 6 Year - 3 ACADEMIC YEAR - 2023-24

Uploaded by

kd14072001
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

NETAJI SHUBASH ENGINEERING COLLEGE

Department of Computer Science and Business System

Subject (Lab): Design and Analysis of Algorithm Code: PCC-CSBS601


Year: 3rd Semester: 6th
Date: 02.03.2024

NAME – SAGAR DE
UNIVERSISTY ROLL – 10931121055
CLASS ROLL – 55
SETION A
SEMESTER – 6TH
YEAR – 3RD
ACADEMIC YEAR – 2023-24
1. Problem Statement: EXPLAIN DIFFERENT DESIGN TECHNIQUES.

 INTRODUCTION:
Algorithms are pivotal in computer science, serving as the cornerstone of problem-solving
methodologies. Effective algorithm design entails devising strategies to solve computational problems
efficiently, taking into account factors such as time complexity, space complexity, and solution optimality.
This report aims to elucidate various design techniques employed in algorithm design and analysis,
shedding light on their intricacies and applicability.

 BRUTE FORCE ALGORITHMS:


Brute force algorithms represent a straightforward approach to problem-solving, exhaustively
exploring all possible solutions to identify the optimal one. While conceptually simple, brute force
algorithms may exhibit high time complexity, making them impractical for large problem instances.
Nevertheless, they serve as a baseline for comparison and can be suitable for small-scale problems where
efficiency is not a primary concern.

 DIVIDE AND CONQURE:


Divide and conquer algorithms break down complex problems into smaller, more manageable
subproblems, recursively solving each subproblem and combining their solutions to obtain the final result.
This technique is exemplified in algorithms such as merge sort and binary search. Divide and conquer
algorithms typically exhibit favorable time complexity, often outperforming brute force approaches for
large problem instances.

 DYNAMIC PROGRAMMING:
Dynamic programming is a paradigm for solving optimization problems by breaking them down into
overlapping subproblems and storing the solutions to these subproblems to avoid redundant computations.
This technique is particularly useful for problems exhibiting optimal substructure, where the optimal
solution can be constructed from optimal solutions to subproblems. Dynamic programming algorithms,
such as the Knapsack problem and Fibonacci sequence computation, offer efficient solutions to a wide
range of problems.

 GREEDY ALGORITHMS:
Greedy algorithms make locally optimal choices at each step with the hope of finding a global
optimum. Unlike dynamic programming, greedy algorithms do not reconsider previous choices, which
can lead to suboptimal solutions in some cases. However, greedy algorithms are often simple to implement
and can offer efficient solutions for certain problem types, such as the minimum spanning tree and the
shortest path problem.

 BACKTRACKING:
Backtracking is a systematic approach to solving problems by incrementally building a solution
candidate and abandoning partial candidates that cannot fulfill the problem constraints. This technique is
commonly used in constraint satisfaction problems, such as the N-Queens problem and Sudoku solving.
Backtracking algorithms explore the solution space efficiently by pruning branches that are guaranteed to
lead to invalid solutions.

 CONCLUSION:
In conclusion, algorithm design and analysis encompass a myriad of techniques tailored to address
diverse computational challenges. From the brute force approach's simplicity to the efficiency of dynamic
programming and the heuristic nature of greedy algorithms, each technique offers unique advantages and
limitations.
2.Problem Statement: WRITE AN ALGORITHM FOR QUICK SORT. EXPLAIN WITH AN EXAMPLE AND
SHOW THE ANALYSIS FOR THE ALGORITHM.

 QUICK SORT ALGORITHM :


Sorting is a way of arranging items in a systematic manner. Quicksort is the widely used sorting
algorithm that makes n log n comparisons in average case for sorting an array of n elements. It is a faster
and highly efficient sorting algorithm. This algorithm follows the divide and conquer approach. Divide
and conquer is a technique of breaking down the algorithms into subproblems, then solving the
subproblems, and combining the results back together to solve the original problem.

DEVIDE: In Divide, first pick a pivot element. After that, partition or rearrange the array into two sub-arrays such
that each element in the left sub-array is less than or equal to the pivot element and each element in the right sub-
array is larger than the pivot element.

CONQURE: Recursively, sort two subarrays with Quicksort.

COMBINE: Combine the already sorted array.

QUICK-SORT ALGORITHM:

#include <iostream>
#include <vector>

using namespace std;

int partition(vector<int>& arr, int low, int high) {


int pivot = arr[high];
int i = low - 1;

for (int j = low; j < high; j++) {

if (arr[j] <= pivot) {


i++;
swap(arr[i], arr[j]);
}
}
swap(arr[i + 1], arr[high]);
return i + 1;
}

void quickSort(vector<int>& arr, int low, int high) {


if (low < high) {

int pi = partition(arr, low, high);


quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
void printArray(vector<int>& arr) {
int n = arr.size();
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
cout << endl;
}

int main() {
vector<int> arr = {10, 7, 8, 9, 1, 5};
int n = arr.size();

cout << "Original array: \n";


printArray(arr);

quickSort(arr, 0, n - 1);

cout << "Sorted array: \n";


printArray(arr);

return 0;
}

EXPLANATION:

1. Partition Function:
o The partition function takes a vector arr, and two integers low and high as input.
o It chooses the last element of the array (arr[high]) as the pivot.
o It then rearranges the array in such a way that all elements smaller than the pivot are placed before
it, and all elements greater than the pivot are placed after it.
o Finally, it returns the index of the pivot element.
2. QuickSort Function:
o The quickSort function implements the QuickSort algorithm recursively.
o It takes a vector arr, and two integers low and high as input.
o If low is less than high, it partitions the array using the partition function.
o It then recursively applies QuickSort to the sub-arrays before and after the pivot.
3. Main Function:
o In the main function, an example array arr is defined.
o The original array is printed.
o QuickSort is applied to the array.
o The sorted array is printed.

EXAMPLE:

Let's take the array {10, 7, 8, 9, 1, 5}:

1.First Iteration:
o Pivot: 5
o After partitioning: {1, 5, 8, 9, 10, 7}
o Partition Index: 1
2.Second Iteration (left partition):
o Pivot: 1
o After partitioning: {1, 5, 8, 9, 10, 7}
o Partition Index: 0
3.Second Iteration (right partition):
o Pivot: 8
o After partitioning: {1, 5, 7, 8, 10, 9}
o Partition Index: 3
4.Third Iteration (right partition):
o Pivot: 10
o After partitioning: {1, 5, 7, 8, 9, 10}
o Partition Index: 4
5.Fourth Iteration (right partition):
o Already sorted, nothing to partition.

ANALYSIS:

Time Complexity:
o Best Case: O(n log n)
o Average Case: O(n log n)
o Worst Case: O(n^2) (Occurs when the pivot is the smallest or largest element in the array,
leading to unbalanced partitions)
Space Complexity:
o O(log n) due to the recursive calls on the call stack.
Stability:
o QuickSort is not a stable sorting algorithm, meaning it does not necessarily preserve the
relative order of equal elements.
In-place Sorting:
o QuickSort is an in-place sorting algorithm as it doesn't require any extra space other than the
input array.
Adaptive:
o QuickSort is not an adaptive sorting algorithm because its performance does not depend on the
initial order of elements.
Comparison with Other Sorting Algorithms:
 QuickSort is often faster than other sorting algorithms like Merge Sort and Heap Sort due to
its in-place partitioning and average-case time complexity of O(n log n).
 However, in worst-case scenarios, QuickSort may degrade to O(n^2), which makes algorithms
like Merge Sort more preferable for guaranteed performance.

CONCLUSION:

QuickSort is a highly efficient and widely used sorting algorithm known for its average-case
performance of O(n log n). Although it can degrade to O(n^2) in the worst-case scenario, its adaptability
to various datasets and in-place sorting make it a popular choice for many applications. By carefully
selecting the pivot and optimizing partitioning, QuickSort can be implemented to achieve excellent
performance in practice.

This explanation and analysis provide a comprehensive understanding of the QuickSort algorithm
in C++, its implementation, example, and its performance characteristics.

You might also like