PARUL UNIVERSITY FACULTY OF ENGINEERING & TECHNOLOGY
SUBJECT: High Performance Computing Laboratory
SUBJECT CODE: 303105356
B. TECH 4th YEAR
PRACTICAL – 3
AIM: Using Divide and Conquer Strategies design a class for Concurrent Quick
Sort using C.
What is Divide and Conquer?
Divide and Conquer is a problem-solving technique where a problem is:
• Divided into smaller sub-problems (usually of the same type),
• Each sub-problem is solved recursively (Conquer step),
• And finally, the results are combined to form the final solution.
This method reduces complexity and improves efficiency, especially in sorting,
searching, and matrix problems.
Real-life analogy:
Imagine sorting a deck of cards by dividing them into smaller piles, sorting
those, and then merging them back in order.
Quick Sort Algorithm (Using Divide and Conquer)
Quick Sort is a sorting algorithm based on the Divide and Conquer approach.
Steps of Quick Sort:
1. Divide:
o Choose a pivot element.
o Rearrange the array such that all elements less than the pivot are
on its left, and all greater than the pivot are on its right.
o This process is called partitioning.
ENROLLMENT NO: 2203031310012 Page | 10
PARUL UNIVERSITY FACULTY OF ENGINEERING & TECHNOLOGY
SUBJECT: High Performance Computing Laboratory
SUBJECT CODE: 303105356
B. TECH 4th YEAR
2. Conquer:
o Recursively apply Quick Sort to the left and right sub-arrays.
3. Combine:
o No merging needed; the array is sorted in-place.
Quick Sort Algorithm (Pseudocode):
QUICK_SORT(arr, left, right):
if left < right:
pivotIndex = PARTITION(arr, left, right)
QUICK_SORT(arr, left, pivotIndex - 1)
QUICK_SORT(arr, pivotIndex + 1, right)
PARTITION(arr, left, right):
pivot = arr[right]
i = left - 1
for j = left to right - 1:
if arr[j] < pivot:
i=i+1
swap arr[i] and arr[j]
swap arr[i+1] and arr[right]
return i + 1
ENROLLMENT NO: 2203031310012 Page | 11
PARUL UNIVERSITY FACULTY OF ENGINEERING & TECHNOLOGY
SUBJECT: High Performance Computing Laboratory
SUBJECT CODE: 303105356
B. TECH 4th YEAR
Time Complexity:
Case Time Complexity
Best Case O(n log n)
Average Case O(n log n)
Worst Case O(n²) (when the array is already sorted in worst pivot choice)
Space Complexity: O(log n) due to recursive stack (in-place sorting)
Advantages of Divide and Conquer:
• Faster Algorithms – Reduces time complexity in many problems.
• Easy Recursion – Naturally fits recursive problem-solving.
• Handles Large Inputs – Efficient for big datasets.
• Supports Parallelism – Sub-problems can be solved concurrently.
• Memory Efficient – Often works in-place with less memory.
• Modular Design – Simplifies debugging and development.
• Wide Applications – Useful in sorting, searching, and graphics.
Quick Sort Code:
%%writefile concurrent_quicksort.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct {
int *arr;
int left;
ENROLLMENT NO: 2203031310012 Page | 12
PARUL UNIVERSITY FACULTY OF ENGINEERING & TECHNOLOGY
SUBJECT: High Performance Computing Laboratory
SUBJECT CODE: 303105356
B. TECH 4th YEAR
int right;
} QuickSortArgs;
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
int partition(int arr[], int left, int right) {
int pivot = arr[right];
int i = left - 1;
for (int j = left; j < right; j++) {
if (arr[j] < pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[right]);
return i + 1;
}
void *quick_sort(void *arg) {
QuickSortArgs *args = (QuickSortArgs *)arg;
int left = args->left;
int right = args->right;
ENROLLMENT NO: 2203031310012 Page | 13
PARUL UNIVERSITY FACULTY OF ENGINEERING & TECHNOLOGY
SUBJECT: High Performance Computing Laboratory
SUBJECT CODE: 303105356
B. TECH 4th YEAR
int *arr = args->arr;
if (left < right) {
int pi = partition(arr, left, right);
QuickSortArgs *leftArgs = malloc(sizeof(QuickSortArgs));
QuickSortArgs *rightArgs = malloc(sizeof(QuickSortArgs));
leftArgs->arr = arr;
leftArgs->left = left;
leftArgs->right = pi - 1;
rightArgs->arr = arr;
rightArgs->left = pi + 1;
rightArgs->right = right;
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, quick_sort, leftArgs);
pthread_create(&thread2, NULL, quick_sort, rightArgs);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
free(leftArgs);
free(rightArgs);
ENROLLMENT NO: 2203031310012 Page | 14
PARUL UNIVERSITY FACULTY OF ENGINEERING & TECHNOLOGY
SUBJECT: High Performance Computing Laboratory
SUBJECT CODE: 303105356
B. TECH 4th YEAR
}
return NULL;
}
int main() {
int n;
printf("Enter number of elements: ");
scanf("%d", &n);
int *arr = malloc(n * sizeof(int));
printf("Enter the elements:\n");
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
QuickSortArgs *args = malloc(sizeof(QuickSortArgs));
args->arr = arr;
args->left = 0;
args->right = n - 1;
pthread_t main_thread;
pthread_create(&main_thread, NULL, quick_sort, args);
pthread_join(main_thread, NULL);
printf("Sorted array: ");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
ENROLLMENT NO: 2203031310012 Page | 15
PARUL UNIVERSITY FACULTY OF ENGINEERING & TECHNOLOGY
SUBJECT: High Performance Computing Laboratory
SUBJECT CODE: 303105356
B. TECH 4th YEAR
printf("\n");
free(arr);
free(args);
return 0;
}
Output:
CONCLUSION:
The divide and conquer strategy is a powerful and versatile approach in
algorithm design, offering numerous advantages in terms of efficiency, clarity,
and applicability. Its ability to break down complex problems into simpler
subproblems makes it a fundamental technique in computer science and
mathematics.
ENROLLMENT NO: 2203031310012 Page | 16