mirror of
https://github.com/TheAlgorithms/C
synced 2024-11-22 05:21:49 +03:00
New sorts
This commit is contained in:
parent
e5dad3fa8d
commit
6e3c6174c6
64
sorting/bitonic_sort.c
Normal file
64
sorting/bitonic_sort.c
Normal file
@ -0,0 +1,64 @@
|
||||
#include <stdio.h>
|
||||
|
||||
// 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;
|
||||
}
|
121
sorting/threeway_merge_sort.c
Normal file
121
sorting/threeway_merge_sort.c
Normal file
@ -0,0 +1,121 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// 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;
|
||||
}
|
118
sorting/tim_sort.c
Normal file
118
sorting/tim_sort.c
Normal file
@ -0,0 +1,118 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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
|
||||
}
|
Loading…
Reference in New Issue
Block a user