Lab Report 1
Lab Report 1
on various input size on randomly generated data. The comparison metric should be the
execution time of each sorting algorithm.
Code:
#include<bits/stdc++.h>
using namespace std;
using namespace chrono;
int i = 0, j = 0, k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k++] = L[i++];
} else {
arr[k++] = R[j++];
}
}
int main() {
int n;
cout << "Enter the number of random elements to generate sort: ";
cin >> n;
vector<int> arr(n);
for (int i = 0; i < n; i++) {
arr[i] = rand() % 100000;
}
start = high_resolution_clock::now();
countingSort(arr_counting);
end = high_resolution_clock::now();
auto counting_sort_time = duration_cast<microseconds>(end - start).count();
start = high_resolution_clock::now();
insertionSort(arr_insertion);
end = high_resolution_clock::now();
auto insertion_sort_time = duration_cast<microseconds>(end - start).count();
cout << "Merge Sort time: " << merge_sort_time << " microseconds" << endl;
cout << "Counting Sort time: " << counting_sort_time << " microseconds" << endl;
cout << "Insertion Sort time: " << insertion_sort_time << " microseconds" << endl;
return 0;
}
Output:
Enter the number of random elements to generate sort: 1000
Merge Sort time: 1534 microseconds
Counting Sort time: 964 microseconds
Insertion Sort time: 3997 microseconds
Result Analysis:
The program compares the performance of three sorting algoritms: Merge Sort,Counting Sort,
and Insertion Sort by measuring their execution times on a random set of 1000 elements.
Merge Sort: Took approximately 1534 microseconds. Merge sort is a comparison-based sorting
algorithm with a time complexity of O(nlogn), which makes it efficient for large datasets.
Counting Sort: Took approximately 964 microseconds,which is the fastest among the three for
this input size.Counting Sort has a time complexity of O(n+k), where k is the range of input
values.
Insertion Sort: Took approximately approximately 3997 microseconds. Insertion Sort is a
simple comparison-based sorting algorithm with a time complexity of O(n^2) for average and
worst cases.Which is reflected in the much higher execution time compared to the other two
algorithm.
Discussion:
Counting Sort id the fastest in this scenario due to its linear time complexity,which is ideal for
the range of values used in the array.
Merge Sort performs efficiently with larger datasets and remains competitive.
Insertion Sort is slower due to its quardratic complexity, making it unsuitable for larger datasets.
Task 2: Implement a Hybrid Sort algorithm where the algorithm switches from Merge
Sort to Insertion Sort when the size of the subarray to be conquered becomes smaller than a
threshold. Determine the optimal threshold empirically. Compare this Hybrid Sort algorithm
with Merge Sort based on various input size and various threshold on randomly generated data.
Code:
#include<bits/stdc++.h>
using namespace std;
int i = 0, j = 0, k = l;
while(i < n1 && j < n2){
if(left_v[i] <= right_v[j]){
arr[k] = left_v[i];
i++;
}
else{
arr[k] = right_v[j];
j++;
}
k++;
}
int m = l + (r - l) / 2;
merge_sort(arr, l, m);
merge_sort(arr, m + 1, r);
merge(arr, l, r, m);
}
}
int main(){
int n;
cout << "Enter the number of random elements to generate sort: ";
cin >> n;
int threshold;
cout << "Enter the threshold value for hybrid merge sort: ";
cin >> threshold;
}
merge_v = arr;
auto t1 = chrono::high_resolution_clock::now();
merge_sort(merge_v, 0, n-1);
auto t2 = chrono::high_resolution_clock::now();
chrono::duration<double> delta_t = t2-t1;
cout << "Merge Sort: " << delta_t.count() <<"\n";
hybrid_v = arr;
t1 = chrono::high_resolution_clock::now();
hybrid_sort(hybrid_v, 0, n - 1,threshold);
t2 = chrono::high_resolution_clock::now();
delta_t = t2-t1;
cout << "Hybrid Sort: " << delta_t.count() <<"\n";
return 0;
}
Output:
Enter the number of random elements to generate sort: 10000
Enter the threshold value for hybrid merge sort: 15
Merge Sort: 0.045873
Hybrid Sort: 0.009355
Result Analysis:
In this sorting algorithm comparison ,the primary goal is to evaluate the performance of three
different sorting algorithms: Merge Sort, Counting Sort and a Hybrid Sort(Which combines
Merge Sort and Insertion Sort for smaller subarrays). Merge sort time taken 0.045873 seconds
.merge sort is a divide-and-conquer algorithm with a time complexity of O(nlogn),
Which is efficient for large datasets.
Hybrid Sort: This sort time taken 0.009355 seconds. The Hybrid Sort Combines Merge Sort for
larger subarrays and switches to Insertion Sort for smaller subarrays (Controlled by a threesold).
Insertion Sort is more efficient for smaller data sets due to its lower constant factor overhead. For
an array of size 10,000 and a threshold of 15 , the hybrid Sort leverages the efficiency of both
algorithms, resulting in better performance than Merge Sort alone. This combinations allows it to
take advantage of Insertion Sort’s simplicity for small segments while retaining Merge Sort’s
efficiency for larger segments.
Discussion:
Hybrid Sort: Outperformed regular Merge Sort by balancing the strengths of both Merge Sort
and Insertion Sort , making it a more versatile solution for larger datasets with a threshold that
optimizes performance. Merge Sort, while not the fastest ,is a reliable and stable
algorithm,consistently performing well across different input sizes and ranges, making it a go-to
general-purpose algorithm when input characteristics are unknown.
Task 3 : Take the Hybrid Sort algorithm from Task 2, instead of Insertion Sort, use Bubble
Sort. Determine the optimal threshold empirically. Make a 3-way comparison between Merge
Sort, Hybrid Sort with Insertion Sort, Hybrid Sort with Bubble Sort algorithm based
on various input size and various threshold on randomly generated data.
Code:
#include<bits/stdc++.h>
using namespace std;
vector<int> left_v(n1),right_v(n2);
for(int i=0;i<n1;i++){
left_v[i]=arr[l+1];
}
for(int i=0;i<n2;i++){
right_v[i]=arr[l+1];
}
int i=0,j=0,k=l;
while(i<n1 && j<n2){
if(left_v[i]<=right_v[j]){
arr[k]=left_v[i];
i++;
}else{
arr[k]=right_v[j];
j++;
}
k++;
}
while(i<n1){
arr[k]=left_v[i];
i++;
k++;
}
while(j<n2){
arr[k]=right_v[j];
j++;
k++;
}
}
int m=l+(r-l)/2;
merge_sort(arr,l,m);
merge_sort(arr,m+1,r);
merge(arr,l,r,m);
}
int main(){
int n;
cout<<"Enter the number of random elemants to genetate for sorting: ";
cin>>n;
int threshold;
cout<<"Enter the thresold value :";
cin>>threshold;
vector<int>arr(n),merge_v,hybrid_insertin_v,hybrid_bubble_v;
for(int i=0;i<n;i++){
arr[i]=rand();
}
//Merge Sort
merge_v=arr;
auto t1=chrono::high_resolution_clock::now();
merge_sort(merge_v,0,n-1);
auto t2=chrono::high_resolution_clock::now();
chrono::duration<double>delta_t=t2-t1;
cout<<"Merge Sort: "<<delta_t.count()<<" seconds\n";
return 0;
}
Output:
Enter the number of random elemants to genetate for sorting: 10000
Enter the thresold value :20
Merge Sort: 0.015546 seconds
Hybrid Sort (with Insertion Sort): 0.014556 seconds
Hybrid Sort (with Bubble Sort): 0.004114 seconds
Result analysis:
In this comparison,we compared the performance of three sorting algorithms: Merge Sort,Hybrid
Sort with Insertion Sort, and hybrid Sort with Bubble Sort,with 10000 randomly generated
elements and a threshold value of 20 for the hybrid algorithm.
Merge Sort: It’s time taken: 0.015546 seconds.Merge Sort has a time complexity of O(nlogn)
and is generally a stable and efficient algorithm for large datasets.
Hybrid Sort (With Insertion Sort): It’s time taken 0.0145546 seconds. This variant sort uses
Merge Sort for larger subarrays but switches to Insertion Sort when the subarray size is smaller
than or equal to the threshold (20 in thid case). Insertion Sort highly efficient for small
datasets.as is an average and worst-case time complexity of O(n^2).
Hybrid Sort( with Bubble Sort ): It’s time taken 0.004114 seconds. Surprisingly , this variant
of hybrid sort, which uses Bubble Sort for small subarrays(size<=20) .Output performed both
Merge Sort and Hybrid Sort with Insertion Sort.Bubble sort is generally inefficient for large
datasets due to its O(n^2) time complexity, but when applied to small subarrays (due to threshold
of 20), it works very efficiently, leading to a total time of just 0.0041 seconds.
Discussion:
The result show that ,for the given threshold and input sizes , Hybrid Sort with Bubble Sort is
surprisingly the fastest ,although its performance may vary with different thresholds and input
sizes. Merge short performed reliably, but it was slightly slower due to the overhead of recursive
calls and merging steps .Hybrid Sort with Insertion Sort was faster than Merge Sort,proving that
Insertion sort is more efficient when used on small subarrays. Hybrid Sort with Bubble Sort
outperformed both Merge Sort and Hybrid Sort with Insertion bubble sort’s Inefficency for large
database,it’s excelled when applied to small subarrays (size<=20) offering the best performance
in this case.
Code:
#include<bits/stdc++.h>
using namespace std;
#define fr(i,n) for(int i=0;i<n;++i)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define lli long long int
const int INF=1e9;
int a[N];
int cnt[V+1];
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int n,d;
cin>>n>>d;
assert(n>=1&&n<=N);
assert(d>=1&&d<=n);
fr(i,n) cin>>a[i];
fr(i,n) assert(a[i]>=0 && a[i]<=V);
int rs=0;
fr(i,d) cnt[a[i]]++;
rep(i,d,n-1){
int acc=0;
int l_m=-1,h_m=-1;
rep(j,0,V){
acc+=cnt[j];
if(l_m==-1 && acc>=int(floor((d+1)/2.0))){
l_m=j;
}
if(h_m==-1 && acc>=int(ceil((d+1)/2.0))){
h_m=j;
}
}
assert(acc == d);
int d_m=l_m + h_m;
if(a[i]>=d_m){
rs++;
}
cnt[a[i-d]]--;
cnt[a[i]]++;
}
cout<<rs<<endl;
return 0;
}
Result: