UNIT 5
UNIT 5
38 27 43 3 9 82 10
38 27 43 3 9 82 10
38 27 43 3 9 82 10
38 27 43 3 9 82 10
Once the size becomes one, the merge process comes into action and starts merging
with sorted array till the complete array is merged
MergeSort Algorithm
The MergeSort function repeatedly divides the array into two halves until we reach a stage
where we try to perform MergeSort on a subarray of size 1 i.e. p == r.
After that, the merge function comes into play and combines the sorted arrays into larger
arrays until the whole array is merged.
MergeSort(A, p, r):
if p > r
return
q = (p+r)/2
mergeSort(A, p, q)
mergeSort(A, q+1, r)
merge(A, p, q, r)
int i, j, k;
i = 0;
j = 0;
k = p;
Maintain indices of copies of sub array and main array
Step 3: Until we reach the end of either L or M, pick larger among elements L and M
and place them in the correct position at A[p..r]
while (i < n1 && j < n2) {
if (L[i] <= M[j]) {
arr[k] = L[i]; i++;
}
else {
arr[k] = M[j];
j++;
}
k++;
}
Comparing individual elements of sorted subarrays until we reach end of one
Step 4: When we run out of elements in either L or M, pick up the remaining elements
and put in A[p..r]
// We exited the earlier loop because j < n2 doesn't hold
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
Copy the remaining elements from the first array to main subarray
// We exited the earlier loop because i < n1 doesn't hold
while (j < n2)
{
arr[k] = M[j];
j++;
k++;
}
}
#include <stdio.h>
// Divide the array into two subarrays, sort them and merge them
void mergeSort(int arr[], int l, int r) {
if (l < r) {
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
// Driver program
int main() {
int arr[] = {6, 5, 12, 10, 9, 1};
int size = sizeof(arr) / sizeof(arr[0]);
Quicksort Algorithm
Quicksort is a sorting algorithm based on the divide and conquer approach where
1. An array is divided into subarrays by selecting a pivot element (element selected
from the array).
While dividing the array, the pivot element should be positioned in such a way that
elements less than pivot are kept on the left side and elements greater than pivot are
on the right side of the pivot.
2. The left and right subarrays are also divided using the same approach. This process
continues until each subarray contains a single element.
3. At this point, elements are already sorted. Finally, elements are combined to form a
sorted array.
Working of Quicksort Algorithm
1. Select the Pivot Element
There are different variations of quicksort where the pivot element is selected from different
positions. Here, we will be selecting the rightmost element of the array as the pivot element.
Put all the smaller elements on the left and greater on the right of pivot element
Here's how we rearrange the array:
1. A pointer is fixed at the pivot element. The pivot element is compared with the
elements beginning from the first index.
2. Comparison of pivot element with element beginning from the first index
3. If the element is greater than the pivot element, a second pointer is set for that
element.
4. If the element is greater than the pivot element, a second pointer is set for that
element.
5. Now, pivot is compared with other elements. If an element smaller than the pivot
element is reached, the smaller element is swapped with the greater element found
earlier.
6. Pivot is compared with other elements.
7. Again, the process is repeated to set the next greater element as the second pointer.
And, swap it with another smaller element.
8. The process is repeated to set the next greater element as the second pointer.
9. The process goes on until the second last element is reached.
10. The process goes on until the second last element is reached.
11. Finally, the pivot element is swapped with the second pointer.
12. Finally, the pivot element is swapped with the second pointer.
3. Divide Subarrays
Pivot elements are again chosen for the left and the right sub-parts separately. And, step 2 is
repeated.
Select pivot element of in each half and put at correct place using recursion
The subarrays are divided until each subarray is formed of a single element. At this point, the
array is already sorted.
Quicksort Code
// Quick sort in C
#include <stdio.h>
// main function
int main() {
int data[] = {8, 7, 2, 1, 0, 9, 6};
printf("Unsorted Array\n");
printArray(data, n);
The Convex Hull problem is a fundamental computational geometry problem, where the goal
is to find the smallest convex polygon called convex hull that can enclose a set of points in a
2D plane. This problem has various applications, such as in computer graphics, geographic
information systems, and collision detection.
In this article, we will learn multiple algorithms for solving the Convex Hull problem and
their implementation in the C programming language.
Example
Input:
Point points[] = {{0, 0}, {0, 4}, {-4, 0}, {5, 0}, {0, -6}, {1, 0}};
Output:
The points in the Convex Hull are:
(-4, 0)
(5, 0)
(0, -6)
(0, 4)
Convex Hull
Convex Hull using Divide and Conquer Algorithm in C
In this approach, we recursively divide the set of points into smaller subsets, finds the convex
hulls for these subsets, and then merges the results to form the final convex hull. This is
similar to the merge sort algorithm in terms of its approach.
Approach:
Start dividing the set of points into two halves based on their x-coordinates. The left
half will contain all points with x-coordinates less than or equal to the median x-
coordinate, and the right half will contain the remaining points.
Recursively apply the divide and conquer approach to find the convex hull for the left
half and the right half.
After finding the convex hulls for the left and right halves, the next step is to merge
these two convex hulls. To do this, find the upper and lower tangents that connect the
two convex hulls.
o The upper tangent is the line that touches both convex hulls and lies above all
the points in both hulls.
o The lower tangent is the line that touches both convex hulls and lies below all
the points in both hulls.
o The points between these tangents form the final convex hull.
Finally, Combine the points from the left convex hull and right convex hull that lie
between the tangents to form the complete convex hull for the entire set of points.
Algorithm
The steps that we’ll follow to solve the problem are:
1. First, we’ll sort the vector containing points in ascending order (according to their x-
coordinates).
2. Next, we’ll divide the points into two halves S1 and S2. The set of points S1 contains
the points to the left of the median, whereas the set S2 contains all the points that are
right to the median.
3. We’ll find the convex hulls for the set S1 and S2 individually. Assuming the convex
hull for S1 is C1, and for S2, it is C2.
4. Now, we’ll merge C1 and C2 such that we get the overall convex hull C.
Greedy Algorithms
A greedy algorithm decides what to do in each step, only based on the current situation,
without a thought of how the total problem looks like.
In other words, a greedy algorithm makes the locally optimal choice in each step, hoping to
find the global optimum solution in the end. Greedy algorithms are a class of algorithms
that make locally optimal choices at each step with the hope of finding a global
optimum solution.
Two properties must be true for a problem for a greedy algorithm to work:
Greedy Choice Property: Means that the problem is so that the solution (the global
optimum) can be reached by making greedy choices in each step (locally optimal
choices).
Optimal Substructure: Means that the optimal solution to a problem, is a collection
of optimal solutions to sub-problems. So solving smaller parts of the problem locally
(by making greedy choices) contributes to the overall solution.
6. then A ← A ∪ {i}
5. do if si ≥ fi
7. j ← i
8. return A
Example: Given 10 activities along with their start and end time as
S = (A1 A2 A3 A4 A5 A6 A7 A8 A9 A10)
Si = (1,2,3,4,7,8,9,9,11,12)
fi = (3,5,4,7,10,9,11,13,12,14)
Solution: The solution to the above Activity scheduling problem using a greedy
strategy is illustrated below:
Arranging the activities in increasing order of end time
Now, schedule A1
Next schedule A3 as A1 and A3 are non-interfering.
Next skip A2 as it is interfering.
Next, schedule A4 as A1 A3 and A4 are non-interfering, then next, schedule A6 as
A1 A3 A4 and A6 are non-interfering.
JobJ
Job sequencing with deadlines is a problem that involves scheduling a set of jobs to
maximize profit while adhering to their respective deadlines. This approach assumes that
each job can be completed in exactly one unit of time. If jobs have different durations, a more
advanced scheduling algorithm might be necessary. Also, if the deadlines are represented as
relative time (e.g., time units after job release), the algorithm would require adjustments
accordingly.
The prime objective of the Job Sequencing with Deadlines algorithm is to complete the given
order of jobs within respective deadlines, resulting in the highest possible profit. To achieve
this, we are given a number of jobs, each associated with a specific deadline, and completing
a job before its deadline earns us a profit. The challenge is to arrange these jobs in a way that
maximizes our total profit.
It is not always possible to complete all of the assigned jobs within the deadlines. For each
job, denoted as Ji, we have a deadline di and a profit pi associated with completing it on time.
Our objective is to find the best solution that maximizes profit while still ensuring that the
jobs are completed within their deadlines.
Here’s how Job Sequencing with Deadlines algorithm works:
Problem Setup
You’re given a list of jobs, where each job has a unique identifier (job_id), a deadline (by
which the job should be completed), and a profit value (the benefit you gain by completing
the job).
Sort the Jobs by Profit
To ensure we consider jobs with higher profits first, sort the jobs in non-increasing order
based on their profit values.
Initialize the Schedule and Available Time Slots
Set up an array to represent the schedule. Initialize all elements to -1, indicating that no job
has been assigned to any time slot. Also, create a boolean array to represent the availability of
time slots, with all elements set to true initially.
Assign Jobs to Time Slots
Go through the sorted jobs one by one. For each job, find the latest available time slot just
before its deadline. If such a time slot is available, assign the job to that slot. If not, skip the
job.
Calculate Total Profit and Scheduled Jobs
Sum up the profits of all the scheduled jobs to get the total profit. Additionally, keep track of
which job is assigned to each time slot.
Output the Results
Finally, display the total profit achieved and the list of jobs that have been scheduled.
Job Sequencing with Deadlines algorithm
Given jobs J(i) with deadline D(i) and profit P(i) for 0≤i≤1, these jobs are arranged in
descending order of profit p1⩾p2⩾p3⩾…⩾pn.
Job-Sequencing-With-Deadline (D, J, n, k)
D(0) := J(0) := 0
k:= 1
J(1) := 1 // means first job is selected
for i = 2 … n do
r:= k
while D(J(r)) > D(i) and D(J(r)) ≠ r do
r:= r – 1
if D(J(r)) ≤ D(i) and D(i) > r then
for l = k … r + 1 by -1 do
J(l + 1): = J(l)
J(r + 1): = i
k:= k + 1
Consider the example: arr[] = {{100, 20}, {60, 10}, {120, 30}}, W = 50.
Sorting: Initially sort the array based on the profit/weight ratio. The sorted array will be
{{60, 10}, {100, 20}, {120, 30}}.
Iteration:
For i = 0, weight = 10 which is less than W. So add this element in the knapsack.
profit = 60 and remaining W = 50 – 10 = 40.
For i = 1, weight = 20 which is less than W. So add this element too. profit = 60 +
100 = 160 and remaining W = 40 – 20 = 20.
For i = 2, weight = 30 is greater than W. So add 20/30 fraction = 2/3 fraction of the
element. Therefore profit = 2/3 * 120 + 160 = 80 + 160 = 240 and remaining W
becomes 0.
So the final profit becomes 240 for W = 50.
ALGORITHM
Follow the given steps to solve the problem using the above approach:
Calculate the ratio (profit/weight) for each item.
Sort all the items in decreasing order of the ratio.
Initialize res = 0, curr_cap = given_cap.
Do the following for every item i in the sorted order:
o If the weight of the current item is less than or equal to the remaining capacity
then add the value of that item into the result
o Else add the current item as much as we can and break out of the loop.
Return res.
weight
⇢
item⇣/ 0 1 2 3 4 5 6
0 0 0 0 0 0 0 0
For filling the first item in the bag: If we follow the above mentioned procedure, the
table will look like the following.
weight
⇢
item⇣/ 0 1 2 3 4 5 6
0 0 0 0 0 0 0 0
weight
⇢
item⇣/ 0 1 2 3 4 5 6
1 1 1 1 1 1
0
1 0 0 0 0 0 0
0 0 0 0 0 0 0 0
1 1 1 1 1 1
0
1 0 0 0 0 0 0
1 1 2 2 2 2
0
2 0 5 5 5 5 5
0 0 0 0 0 0 0 0
weight
⇢
item⇣/ 0 1 2 3 4 5 6
1 1 1 1 1 1
0
1 0 0 0 0 0 0
1 1 2 2 2 2
0
2 0 5 5 5 5 5
1 1 4 5 5 6
0
3 0 5 0 0 5 5
#SOLVE NUMERICAL WAY TAUGHT IN CLASS USING MATRIX THIS IS JUST FOR
EXAMPLE.
Sr.
No 0/1 knapsack problem Fractional knapsack problem
The 0/1 knapsack problem has an The fractional knapsack problem also has
2. optimal structure. an optimal structure.
0/1 knapsack problem, finds a most In the fractional knapsack problem, finds
valuable subset item with a total value a most valuable subset item with a total
4. less than equal to weight. value equal to the weight.
The 0/1 knapsack does not have greedy The fraction knapsack do have greedy
6. choice property choice property.