0% found this document useful (0 votes)
3 views15 pages

ITA Unit 2 Answer

The document outlines the curriculum for the Introduction to Algorithms course at Francis Xavier Engineering College, focusing on the Divide-and-Conquer methodology, including algorithms like Merge Sort, Quick Sort, and Strassen’s Matrix Multiplication. It includes detailed explanations of recursion in Merge Sort, the partitioning process in Quick Sort, and the complexities of these algorithms. Additionally, it covers binary search applications and modifications for finding occurrences of elements in sorted arrays.

Uploaded by

madboyaswin2206
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)
3 views15 pages

ITA Unit 2 Answer

The document outlines the curriculum for the Introduction to Algorithms course at Francis Xavier Engineering College, focusing on the Divide-and-Conquer methodology, including algorithms like Merge Sort, Quick Sort, and Strassen’s Matrix Multiplication. It includes detailed explanations of recursion in Merge Sort, the partitioning process in Quick Sort, and the complexities of these algorithms. Additionally, it covers binary search applications and modifications for finding occurrences of elements in sorted arrays.

Uploaded by

madboyaswin2206
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/ 15

FRANCIS XAVIER ENGINEERING COLLEGE, TIRUNELVELI

(An Autonomous Institution)

DEPARTMENT OF INFORMATION TECHNOLOGY

ACADEMIC YEAR: 2024-25/EVEN BATCH: 2023 – 27 SEM: 04

Course Code | Name: 21IT4601 – INTRODUCTION TO ALGORITHMS

Unit II - Divide-and-Conquer

Divide and conquer methodology – Merge sort – Quick sort – Binary search –
Multiplication of Large Integers – Strassen’s Matrix Multiplication.

Course Outcome – CO2: Design algorithms to solve problems using divide and
conquer approach.

PART – A
Q. No Question
1 What role does recursion play in the Merge Sort algorithm?
Recursion in Merge Sort:
• It divides the Aay into two halves recursively until each subArray has
one element.
• Then, it merges the sorted subArrays back into a single sorted Array.
• This ensures an efficient sorting process with a time complexity of
O(n log n).

Given the Array [3, 8, 5, 2, 7, 6, 4] and pivot = 4, determine the position of the
2.
pivot after one partitioning step.
Pivot in Quick Sort:
• The given Aay is [3, 8, 5, 2, 7, 6, 4] with pivot = 4.
• After partitioning, elements smaller than 4 move left, and larger ones
move right.
• [3, 2, 5, 8, 7, 6, 4]. [3, 2, 4, 8, 7, 6, 5].
• The pivot 4 ends up at index 2 with the Array as [3, 2, 4, 8, 7, 6, 5].

State the time and space complexity of Quick Sort in the best case and the
3
worst case.
Complexity of Quick Sort:
• Best case occurs when the pivot divides the Aay evenly, giving O(n log
n) complexity.
• Worst case happens when the pivot is always the smallest or largest,
leading to O(n²) complexity.
• Choosing a good pivot (like median-of-three) helps improve
efficiency.
At which step will the binary search find the key 23 in the sorted Array [12,
18, 23, 34, 45, 56, 67].
4
Binary Search (Key = 23):
• The sorted Array is [12, 18, 23, 34, 45, 56, 67].
• First, mid = 34 (index 3), so search moves to the left half.
• Second, mid = 23 (index 2), so key 23 is found in step 2.

Can Binary Search be applied to a dynamic Array whose size changes during
5
execution? Why or why not?
Binary Search on Dynamic Arrays:
• Binary search requires a sorted Array for efficient searching.
• If elements are inserted or deleted dynamically, sorting must be done
again.
• Thus, applying binary search directly on a changing Array is
inefficient.

6 How Strassen’s method reduces the number of multiplications in matrix


operations?
Strassen’s Method:
• Traditional matrix multiplication requires 8 multiplications per step.
• Strassen's algorithm reduces this to 7 multiplications, improving
efficiency.
• This reduces time complexity from O(n³) to approximately O(n²).

PART – B

Q.No Question
Write merge sort algorithm and implement it to sort the following Array of
integers in ascending order:
5, 2, 8, 3, 1, 6, 4

Merge Sort:
Merge sort is a sorting algorithm that follows the divide-and-
conquer approach. It works by recursively dividing the input Array into
smaller subArrays and sorting those subAarrys then merging them back
together to obtain the sorted Array.

The process of merge sort is to divide the Aay into two halves, sort each half,
and then merge the sorted halves back together. This process is repeated
1 i)
until the entire Array is sorted.

void merge(int C[], int left, int mid, int right)


{
int m = mid - left + 1;
int n= right – mid;

// Create temporary Arrays


int A[m], B[n];

// Copy data to temporary Arrays


for (int i = 0; i < n1; i++)
Q.No Question
A[i] = Arr[left + i];

for (int j = 0; j < n2; j++)


B[j]= Arr[mid + 1 + j];

// Merge the two Arrays back into A[]


int i = 0, j = 0, k = left;
while (i < m && j < n)
{
if( A[i]<B[j]){
C[k++] = A[i++];
}
else {
C[k++] = B[j++]
}
}

// Copy remaining elements of A, if any


for(; i<n1;i++)
{
C[k++] = A[i];
}

// Copy remaining elements of B, if any


for(; j<n1;j++)
{ C[k++] = B[j];
}
}

// Function to implement Merge Sort


void mergeSort(int Arr[], int left, int right) {
if (left < right) {
int mid = left + right / 2;

// Recursively sort the first and second halves


mergeSort(Arr, left, mid);
mergeSort(Arr, mid + 1, right);

// Merge the sorted halves


merge(Arr, left, mid, right);
}
}

Implementation of Merge sort in the Array :

A[] = {5, 2, 8, 3, 1, 6, 4}
Q.No Question
Split the Array :

Left: {5, 2, 8, 3} Right: {1, 6, 4}

Left: {5, 2} | {8, 3} Right: {1, 6} | {4}

Left:{5} {2} | {8} {3} Right: {1} {6} | {4}

Merge the parts:

Merge {5, 2} → {2, 5} Merge {1, 6} → {1, 6}


Merge {8, 3} → {3, 8} Merge {4} → {4}

Merge {2, 5} and {3, 8} → {2, 3, 5, 8} Merge {1, 6} and {4} → {1, 4, 6}

Merge {2, 3, 5, 8} and {1, 4, 6} → {1, 2, 3, 4, 5, 6, 8}

[5, 2, 8, 3, 1, 6, 4]
/ \
[5, 2, 8, 3] [1, 6, 4]
/ \ / \
[5, 2] [8, 3] [1, 6] [4]
/ \ / \ / \
[5] [2] [8] [3] [1] [6]

\ / \ / \ /
[2, 5] [3, 8] [1, 6]
\ / \
[2, 3, 5, 8] [1, 4, 6]
\ /
[1, 2, 3, 4, 5, 6, 8]
Q.No Question
Write about the principle behind the Quick Sort, a Divide and Conquer
algorithm, to sort an Aay, A[] in ascending order. Given an Array, A[], with
starting index low and ending index high, Write the functions partition()
and quickSort(). Use the First element as the pivot so that all elements less
than or equal to the pivot come before it, and elements greater than the pivot
follow it.

QuickSort is a sorting algorithm based on the Divide and Conquer that picks
an element as a pivot and partitions the given Array around the picked pivot
by placing the pivot in its correct position in the sorted Array.
It is based on positioning the element in its sorted position. An element is in
sorted position if all the elements to left of it is less and all the elements to
right of it is greater than pivot element.

QuickSort works on the principle of divide and conquer, breaking down the
problem into smaller sub-problems.

2 i) There are mainly three steps in the algorithm:


1. Choose a Pivot: Select an element from the Array as the pivot. The
choice of pivot can vary (e.g., first element, last element, random
element, or median).
2. Partition the Aay: ReAange the Array around the pivot. After
partitioning, all elements smaller than the pivot will be on its left, and
all elements greater than the pivot will be on its right. The pivot is then
in its correct position, and we obtain the index of the pivot.
3. Recursively Call: Recursively apply the same process to the two
partitioned sub-Arrays (left and right of the pivot).
4. Base Case: The recursion stops when there is only one element left in
the sub-Aay, as a single element is already sorted.

// Partition function for Quick Sort (Ascending Order)


int partition(int A[], int l, int h)
{
int pivot = A[l];
// First element as pivot
int i = l + 1,
j = h;
Q.No Question
while (i <= j) {
// Find element greater than pivot from the left
while (A[i] < =pivot)
i++;

// Find element smaller than pivot from the right


while (A[j] > pivot)
j--;

if (i < j) {
// Swap elements to correct position
swap(&A[i], &A[j]);
}
}
// Swap pivot element
swap(&A[l], &A[j]);

// Return the pivot index


return j;
}

// Quick Sort function


void quickSort(int A[], int l, int h) {
if (l < h) {
int j = partition(A, l, h);
quickSort(A, l, j - 1); // Sort left subArray
quickSort(A, j+ 1, h); // Sort right subArray
}
}
Initial unsorted array
9 -3 5 2 6 8 -6 1 3
Pivo
j
t i
H
L
i
i
i
i
i
i
i
3 -3 5 2 6 8 -6 1 9
Q.No Question

3 -3 5 2 6 8 -6 1
Pivot j
i
L H
i j
3 -3 1 2 6 8 -6 5
i
i j
3 -3 1 2 -6 8 6 5
i
i j
j i
-6 -3 1 2 3 8 6 5

8 6 5
-6 -3 1 2
Piv H
Piv H i
i l j
j
i
j
5 6 8
-6 -3 1 2

Sort the following Array of characters using Quick Sort:


['e', 'd', 'c', 'a', 'b', 'f'].
Provide the sorted Array and the partitioning process step-by-step. State
the time and space complexity of quick sort.

QuickSort is a sorting algorithm based on the Divide and Conquer that picks
an element as a pivot and partitions the given Array around the picked pivot
by placing the pivot in its correct position in the sorted Array.
It is based on positioning the element in its sorted position. An element is in
3 i) sorted position if all the elements to left of it is less and all the elements to
right of it is greater than pivot element.

QuickSort works on the principle of divide and conquer, breaking down the
problem into smaller sub-problems.

// Partition function for Quick Sort (Ascending Order)


// Partition function for Quick Sort (Ascending Order)
int partition(int A[], int l, int h)
{
int pivot = A[l];
Q.No Question
// First element as pivot
int i = l + 1,
j = h;
while (i <=j) {
// Find element greater than pivot from the left
while (A[i] < =pivot)
i++;

// Find element smaller than pivot from the right


while (A[j] > pivot)
j--;

if (i < j) {
// Swap elements to correct position
swap(&A[i], &A[j]);
}
}
// Swap pivot element
swap(&A[low], &A[j]);

// Return the pivot index


return j;
}
// Quick Sort function
void quickSort(int A[], int l, int h) {
if (l < h) {
int j = partition(A, l, h);
quickSort(A, l, j - 1); // Sort left subArray
quickSort(A, j+ 1, h); // Sort right subArray
}
}

['e', 'd', 'c', 'a', 'b', 'f'].

e d c a b f
Piv i j
l h
i
i
i
i
j
b d c a e f
Q.No Question

b d c a
piv i j
b a c d
j>i swap
j i
pivot
a b c d

Time Complexity Analysis:


• Best Case (O(n log n)): When the pivot divides the Array into nearly
equal halves.
• Average Case (O(n log n)): Generally occurs when elements are
randomly distributed.
• Worst Case (O(n²)): Happens if the pivot is always the smallest or
largest element (e.g., already sorted data).
This implementation ensures efficient sorting with minimal overhead,
making it ideal for large datasets.

Modify the binary search algorithm to find the position of the first
occurrence of a value that may appear more than once in the ordered list.
Check that your algorithm is still O(log n). Find the index of the first
occurrence of the target element (2) using binary search:
1, 2, 2, 2, 3, 4, 5
Also Find the total number of occurrences of a target element in a sorted
Array using Binary Search.

// Function to find first occurrence


int findFirstOccurrence(int A[], int n, int target) {
int low = 0, high = n - 1, result = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
4 i)
if (A[mid] == target) {
result = mid;
high = mid - 1; // Continue searching in the left half
} else if (A[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return result;
}
Q.No Question
// Function to find last occurrence
int findLastOccurrence(int A[], int n, int target) {
int low = 0, high = n - 1, result = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (A[mid] == target) {
result = mid;
low = mid + 1; // Continue searching in the right half
} else if (A[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return result;
}

// Function to count total occurrences


int countOccurrences(int A[], int n, int target) {
int first = findFirstOccurrence(A, n, target);
int last = findLastOccurrence(A, n, target);
if (first == -1) return 0; // Target not found
return last - first + 1;
}

1, 2, 2, 2, 3, 4, 5
First occurrence index=2
Index 0 1 2 3 4 5 6
element 1 2 2 2 3 4 5
Mid
low high
Res=3
low high
Mid
Res=1

Last occurrence index=3


Q.No Question
0 1 2 3 4 5 6
1 2 2 2 3 4 5
Mid
low high
Res=3
low mid high
low
high
Count = last occurrence – first occurrence +1
= 3-1+1 = 3
Given two 3x3 matrices:
123456789 × 10 11 12 13 14 15 16 17 18
Multiply them using Strassen's matrix multiplication and compare the result
with the standard matrix multiplication method.

5 i)
Q.No Question
Q.No Question

PART – C

Q. No Question
A logistics company is organizing a shipment of packages to different cities.
Each package has a unique delivery priority score, and the company wants
to Aange the packages in descending order of priority for efficient delivery.
The number of packages is large, and the system must process the sorting
operation with minimal computational overhead.
Problem:
Given a large dataset of package priority scores, sort the scores . recommend
a suitable sort.
Objective:
1 i)
Implement the sort to efficiently sort the packages' priority scores in
descending order and analyze its performance in terms of time complexity.
packages_priority_scores = [56, 78, 45, 90, 12, 65, 83]
output : [90, 83, 78, 65, 56, 45, 12]

Recommended Sorting Algorithm:


Given a large dataset of package priority scores to sort the scores , Quick
Sort is recommended.
Q. No Question

Reason for Choosing Quick Sort:


1. Efficiency: Quick Sort has an average-case time complexity of O(n
log n), making it well-suited for sorting large datasets.
2. In-Place Sorting: It requires minimal additional space (O(log n)
auxiliary space) compared to Merge Sort (O(n) space complexity).
3. Performance on Large Data: Quick Sort is typically faster than Heap
Sort and Merge Sort due to lower constant factors and cache
efficiency.

Implementation

#include <stdio.h>

// Function to swap two elements


void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}

// Partition function for Quick Sort (Descending Order)


int partition(int A[], int l, int h) {
int pivot = A[l]; // First element as pivot
int i = l + 1, j = h;

while (i < =j) {


// Find element smaller than pivot from the right
while (A[i] > pivot)
i++;
// Find element greater than pivot from the left
while (A[j] <= pivot)
j--;

if (i < j) {
swap(&A[i], &A[j]); // Swap elements to correct position
}
}

// Swap pivot with the last greater element


swap(&A[l], &A[j]);

return j; // Return the pivot index


}
Q. No Question
// Quick Sort function
void quickSort(int A[], int l, int h) {
if (l < h) {
int j = partition(A, l, h);
quickSort(A, l, j - 1); // Sort left subArray
quickSort(A, j+ 1, h); // Sort right subArray
}
}

// Function to print the Array


void printArray(int A[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
}

// Main function
int main() {
int scores[] = {56, 78, 45, 90, 12, 65, 83};
int n = sizeof(scores) / sizeof(scores[0]);

printf("Original Array:\n");
printArray(scores, n);

// Perform Quick Sort


quickSort(scores, 0, n-1);

printf("Sorted Array (Descending Order):\n");


printArray(scores, n);

return 0;
}

Time Complexity Analysis:


• Best Case (O(n log n)): When the pivot divides the Aay into nearly
equal halves.
• Average Case (O(n log n)): Generally occurs when elements are
randomly distributed.
• Worst Case (O(n²)): Happens if the pivot is always the smallest or
largest element (e.g., already sorted data).
This implementation ensures efficient sorting with minimal overhead,
making it ideal for large datasets.

Learning Resources:https://www.techinterviewhandbook.org/algorithms/sorting-
searching/

You might also like