From 6e3c6174c6607f990ac63997fb34ec3ab6eb4d99 Mon Sep 17 00:00:00 2001 From: SpEXterXD Date: Sun, 6 Oct 2024 19:17:52 +0530 Subject: [PATCH] New sorts --- sorting/bitonic_sort.c | 64 ++++++++++++++++++ sorting/threeway_merge_sort.c | 121 ++++++++++++++++++++++++++++++++++ sorting/tim_sort.c | 118 +++++++++++++++++++++++++++++++++ 3 files changed, 303 insertions(+) create mode 100644 sorting/bitonic_sort.c create mode 100644 sorting/threeway_merge_sort.c create mode 100644 sorting/tim_sort.c diff --git a/sorting/bitonic_sort.c b/sorting/bitonic_sort.c new file mode 100644 index 00000000..ee460ab6 --- /dev/null +++ b/sorting/bitonic_sort.c @@ -0,0 +1,64 @@ +#include + +// Function to compare and swap elements +void compareAndSwap(int *x, int *y, int order) { + if ((order == 1 && *x > *y) || (order == 0 && *x < *y)) { + int temp = *x; + *x = *y; + *y = temp; + } +} + +// Function to perform bitonic merge +void bitonicMerge(int arr[], int low, int cnt, int order) { + if (cnt > 1) { + int k = cnt / 2; + for (int i = low; i < low + k; i++) { + compareAndSwap(&arr[i], &arr[i + k], order); + } + bitonicMerge(arr, low, k, order); // First half + bitonicMerge(arr, low + k, k, order); // Second half + } +} + +// Function to sort a bitonic sequence +void bitonicSort(int arr[], int low, int cnt, int order) { + if (cnt > 1) { + int k = cnt / 2; + // Sort first half in ascending order + bitonicSort(arr, low, k, 1); + // Sort second half in descending order + bitonicSort(arr, low + k, k, 0); + // Merge the whole sequence in order + bitonicMerge(arr, low, cnt, order); + } +} + +// Helper function to start the sorting process +void sort(int arr[], int n, int order) { + bitonicSort(arr, 0, n, order); +} + +// Function to print the array +void printArray(int arr[], int size) { + for (int i = 0; i < size; i++) + printf("%d ", arr[i]); + printf("\n"); +} + +// Main function to test Bitonic Sort +int main() { + int arr[] = {12, 4, 7, 9, 6, 3, 8, 10}; + int n = sizeof(arr) / sizeof(arr[0]); + + printf("Original array: "); + printArray(arr, n); + + // Sort the array in ascending order + sort(arr, n, 1); + + printf("Sorted array: "); + printArray(arr, n); + + return 0; +} diff --git a/sorting/threeway_merge_sort.c b/sorting/threeway_merge_sort.c new file mode 100644 index 00000000..79567604 --- /dev/null +++ b/sorting/threeway_merge_sort.c @@ -0,0 +1,121 @@ +#include +#include + +// Function to merge three sorted subarrays +void merge(int arr[], int left, int mid1, int mid2, int right) { + int i, j, k; + int n1 = mid1 - left + 1; // Size of the first subarray + int n2 = mid2 - mid1; // Size of the second subarray + int n3 = right - mid2; // Size of the third subarray + + // Temporary arrays + int *L = (int*)malloc(n1 * sizeof(int)); + int *M = (int*)malloc(n2 * sizeof(int)); + int *R = (int*)malloc(n3 * sizeof(int)); + + // Copy data to temporary arrays + for (i = 0; i < n1; i++) + L[i] = arr[left + i]; + for (j = 0; j < n2; j++) + M[j] = arr[mid1 + 1 + j]; + for (k = 0; k < n3; k++) + R[k] = arr[mid2 + 1 + k]; + + // Merge the temporary arrays back into arr[] + i = 0; j = 0; k = 0; + int idx = left; + + while (i < n1 && j < n2 && k < n3) { + if (L[i] <= M[j] && L[i] <= R[k]) { + arr[idx++] = L[i++]; + } else if (M[j] <= L[i] && M[j] <= R[k]) { + arr[idx++] = M[j++]; + } else { + arr[idx++] = R[k++]; + } + } + + // Merge remaining elements of L[] + while (i < n1 && j < n2) { + if (L[i] <= M[j]) { + arr[idx++] = L[i++]; + } else { + arr[idx++] = M[j++]; + } + } + + while (j < n2 && k < n3) { + if (M[j] <= R[k]) { + arr[idx++] = M[j++]; + } else { + arr[idx++] = R[k++]; + } + } + + while (i < n1 && k < n3) { + if (L[i] <= R[k]) { + arr[idx++] = L[i++]; + } else { + arr[idx++] = R[k++]; + } + } + + // Copy remaining elements of L[] + while (i < n1) { + arr[idx++] = L[i++]; + } + + // Copy remaining elements of M[] + while (j < n2) { + arr[idx++] = M[j++]; + } + + // Copy remaining elements of R[] + while (k < n3) { + arr[idx++] = R[k++]; + } + + // Free temporary arrays + free(L); + free(M); + free(R); +} + +// Recursive function to perform 3-way MergeSort +void mergeSort3Way(int arr[], int left, int right) { + if (left < right) { + int mid1 = left + (right - left) / 3; + int mid2 = mid1 + (right - left) / 3 + 1; + + // Recursively sort three subarrays + mergeSort3Way(arr, left, mid1); + mergeSort3Way(arr, mid1 + 1, mid2); + mergeSort3Way(arr, mid2 + 1, right); + + // Merge the sorted subarrays + merge(arr, left, mid1, mid2, right); + } +} + +// Function to print the array +void printArray(int arr[], int size) { + for (int i = 0; i < size; i++) + printf("%d ", arr[i]); + printf("\n"); +} + +// Main function to test 3-way MergeSort +int main() { + int arr[] = {12, 4, 7, 9, 6, 3, 8, 10}; + int n = sizeof(arr) / sizeof(arr[0]); + + printf("Original array: "); + printArray(arr, n); + + mergeSort3Way(arr, 0, n - 1); // Sort the array + + printf("Sorted array: "); + printArray(arr, n); + + return 0; +} diff --git a/sorting/tim_sort.c b/sorting/tim_sort.c new file mode 100644 index 00000000..621f2f2c --- /dev/null +++ b/sorting/tim_sort.c @@ -0,0 +1,118 @@ +#include +#include +#include + +#define RUN 32 // Size of the run + +// Function to perform insertion sort on a subarray +void insertionSort(int arr[], int left, int right) { + for (int i = left + 1; i <= right; i++) { + int key = arr[i]; // Element to be inserted + int j = i - 1; + + // Move elements of arr[left..i-1] that are greater than key + // to one position ahead of their current position + while (j >= left && arr[j] > key) { + arr[j + 1] = arr[j]; + j--; + } + arr[j + 1] = key; // Place the key in its correct position + } +} + +// Function to merge two sorted subarrays +void merge(int arr[], int left, int mid, int right) { + int i, j, k; + int n1 = mid - left + 1; // Size of left subarray + int n2 = right - mid; // Size of right subarray + + // Create temporary arrays for left and right subarrays + int *L = (int*)malloc(n1 * sizeof(int)); + int *R = (int*)malloc(n2 * sizeof(int)); + + // Copy data to temporary arrays L[] and R[] + for (i = 0; i < n1; i++) + L[i] = arr[left + i]; + for (j = 0; j < n2; j++) + R[j] = arr[mid + 1 + j]; + + // Merge the temporary arrays back into arr[left..right] + i = 0; + j = 0; + k = left; + + // Merge while both subarrays have elements + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; // If the current element of L[] is smaller + i++; + } else { + arr[k] = R[j]; // If the current element of R[] is smaller + j++; + } + k++; + } + + // Copy remaining elements of L[], if any + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + // Copy remaining elements of R[], if any + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } + + // Free the temporary arrays + free(L); + free(R); +} + +// Main TimSort function +void timSort(int arr[], int n) { + // Step 1: Sort individual subarrays of size RUN + for (int start = 0; start < n; start += RUN) { + int end = (start + RUN - 1 < n - 1) ? (start + RUN - 1) : (n - 1); + insertionSort(arr, start, end); // Sort the run using insertion sort + } + + // Step 2: Merge the sorted runs + for (int size = RUN; size < n; size *= 2) { // Double the size of the run + for (int left = 0; left < n; left += 2 * size) { + int mid = left + size - 1; // Ending index of the left subarray + int right = ((left + 2 * size - 1) < (n - 1)) ? (left + 2 * size - 1) : (n - 1); // Ending index of the right subarray + + // Merge the two subarrays if valid + if (mid < right) { + merge(arr, left, mid, right); + } + } + } +} + +// Function to print the array +void printArray(int arr[], int size) { + for (int i = 0; i < size; i++) + printf("%d ", arr[i]); // Print each element + printf("\n"); // New line after printing the array +} + +// Main function to test the TimSort implementation +int main() { + int arr[] = {5, 21, 7, 23, 19, 10, 1, 34, 0}; // Example array + int n = sizeof(arr) / sizeof(arr[0]); // Calculate number of elements in the array + + printf("Original array: "); + printArray(arr, n); // Print the original array + + timSort(arr, n); // Call TimSort on the array + + printf("Sorted array: "); + printArray(arr, n); // Print the sorted array + + return 0; // End of program +}