diff --git a/code/03-tree-detection.c b/code/03-tree-detection.c index 149f7dd..4fc20d1 100644 --- a/code/03-tree-detection.c +++ b/code/03-tree-detection.c @@ -31,8 +31,7 @@ int search_cycle(int graph[N][N], int v, int *visited, int parent) { int all_visited(int *visited) { int i; // Find first unvisited vertex - for (i = 0; i < N && visited[i]; ++i) - ; + for (i = 0; i < N && visited[i]; ++i); return i == N; // Return true if no unvisited vertices found, false otherwise } diff --git a/code/10-bubble_sort.c b/code/10-bubble_sort.c new file mode 100644 index 0000000..35a1e1d --- /dev/null +++ b/code/10-bubble_sort.c @@ -0,0 +1,77 @@ +#include +#include +#include + +/** + * Function to perform Bubble Sort on an array. + * + * @param arr The array to sort. + * @param n The size of the array. + */ +void bubble_sort(int arr[], int n) { + for (int i = 0; i < n - 1; i++) { + for (int j = 0; j < n - i - 1; j++) { + if (arr[j] > arr[j + 1]) { + // Swap arr[j] and arr[j + 1] + int temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } +} + +/** + * Main function to demonstrate Bubble Sort and measure execution time. + */ +int main() { + int N_values[] = {10000, 20000, 30000, 40000}; + int num_tests = sizeof(N_values) / sizeof(N_values[0]); + + for (int t = 0; t < num_tests; t++) { + int N = N_values[t]; + int *arr = (int *)malloc(N * sizeof(int)); + + // Seed the random number generator + srand(time(NULL)); + + // Fill the array with random integers + for (int i = 0; i < N; i++) { + arr[i] = rand() % N; + } + + // Measure the start time + clock_t start_time = clock(); + + // Perform Bubble Sort + bubble_sort(arr, N); + + // Measure the end time + clock_t end_time = clock(); + + // Calculate the elapsed time in seconds + double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC; + + // Verify that the array is sorted + int is_sorted = 1; + for (int i = 1; i < N; i++) { + if (arr[i - 1] > arr[i]) { + is_sorted = 0; + break; + } + } + + // Print the result and time + printf("Bubble Sort with N = %d\n", N); + if (is_sorted) + printf("Array is sorted.\n"); + else + printf("Array is NOT sorted.\n"); + printf("Time taken: %f seconds\n\n", time_spent); + + // Free the allocated memory + free(arr); + } + + return 0; +} diff --git a/code/11-selection_sort.c b/code/11-selection_sort.c new file mode 100644 index 0000000..098e355 --- /dev/null +++ b/code/11-selection_sort.c @@ -0,0 +1,80 @@ +#include +#include +#include + +/** + * Function to perform Selection Sort on an array. + * + * @param arr The array to sort. + * @param n The size of the array. + */ +void selection_sort(int arr[], int n) { + for (int i = 0; i < n - 1; i++) { + int min_index = i; + + // Find the minimum element in the unsorted portion + for (int j = i + 1; j < n; j++) { + if (arr[j] < arr[min_index]) min_index = j; + } + + // Swap the found minimum element with the first unsorted element + int temp = arr[min_index]; + arr[min_index] = arr[i]; + arr[i] = temp; + } +} + +/** + * Main function to demonstrate Selection Sort and measure execution time. + */ +int main() { + int N_values[] = {10000, 20000, 30000, 40000}; + int num_tests = sizeof(N_values) / sizeof(N_values[0]); + + for (int t = 0; t < num_tests; t++) { + int N = N_values[t]; + int *arr = (int *)malloc(N * sizeof(int)); + + // Seed the random number generator + srand(time(NULL)); + + // Fill the array with random integers + for (int i = 0; i < N; i++) { + arr[i] = rand() % N; + } + + // Measure the start time + clock_t start_time = clock(); + + // Perform Selection Sort + selection_sort(arr, N); + + // Measure the end time + clock_t end_time = clock(); + + // Calculate the elapsed time in seconds + double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC; + + // Verify that the array is sorted + int is_sorted = 1; + for (int i = 1; i < N; i++) { + if (arr[i - 1] > arr[i]) { + is_sorted = 0; + break; + } + } + + // Print the result and time + printf("Selection Sort with N = %d\n", N); + if (is_sorted) + printf("Array is sorted.\n"); + else + printf("Array is NOT sorted.\n"); + printf("Time taken: %f seconds\n\n", time_spent); + + // Free the allocated memory + free(arr); + } + + return 0; +} diff --git a/code/12-insertion_sort.c b/code/12-insertion_sort.c new file mode 100644 index 0000000..ddbe91c --- /dev/null +++ b/code/12-insertion_sort.c @@ -0,0 +1,79 @@ +#include +#include +#include + +/** + * Function to perform Insertion Sort on an array. + * + * @param arr The array to sort. + * @param n The size of the array. + */ +void insertion_sort(int arr[], int n) { + for (int i = 1; i < n; i++) { + int key = arr[i]; + int j = i - 1; + + // Move elements of arr[0..i-1], that are greater than key, + // to one position ahead of their current position + while (j >= 0 && arr[j] > key) { + arr[j + 1] = arr[j]; + j = j - 1; + } + arr[j + 1] = key; + } +} + +/** + * Main function to demonstrate Insertion Sort and measure execution time. + */ +int main() { + int N_values[] = {10000, 20000, 30000, 40000}; + int num_tests = sizeof(N_values) / sizeof(N_values[0]); + + for (int t = 0; t < num_tests; t++) { + int N = N_values[t]; + int *arr = (int *)malloc(N * sizeof(int)); + + // Seed the random number generator + srand(time(NULL)); + + // Fill the array with random integers + for (int i = 0; i < N; i++) { + arr[i] = rand() % N; + } + + // Measure the start time + clock_t start_time = clock(); + + // Perform Insertion Sort + insertion_sort(arr, N); + + // Measure the end time + clock_t end_time = clock(); + + // Calculate the elapsed time in seconds + double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC; + + // Verify that the array is sorted + int is_sorted = 1; + for (int i = 1; i < N; i++) { + if (arr[i - 1] > arr[i]) { + is_sorted = 0; + break; + } + } + + // Print the result and time + printf("Insertion Sort with N = %d\n", N); + if (is_sorted) + printf("Array is sorted.\n"); + else + printf("Array is NOT sorted.\n"); + printf("Time taken: %f seconds\n\n", time_spent); + + // Free the allocated memory + free(arr); + } + + return 0; +} diff --git a/code/13-merge_sort.c b/code/13-merge_sort.c new file mode 100644 index 0000000..be221e7 --- /dev/null +++ b/code/13-merge_sort.c @@ -0,0 +1,124 @@ +#include +#include +#include + +/** + * Function to merge two subarrays of arr[]. + * First subarray is arr[left..mid] + * Second subarray is arr[mid+1..right] + * + * @param arr The main array containing both subarrays. + * @param left The starting index of the first subarray. + * @param mid The ending index of the first subarray. + * @param right The ending index of the second subarray. + */ +void merge(int arr[], int left, int mid, int right) { + int n1 = mid - left + 1; + int n2 = right - mid; + + // Create temp arrays + int *L = (int *)malloc(n1 * sizeof(int)); + int *R = (int *)malloc(n2 * sizeof(int)); + + // Copy data to temp arrays L[] and R[] + for (int i = 0; i < n1; i++) L[i] = arr[left + i]; + for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j]; + + // Merge the temp arrays back into arr[left..right] + int i = 0; // Initial index of first subarray + int j = 0; // Initial index of second subarray + int k = left; // Initial index of merged subarray + + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k++] = L[i++]; + } else { + arr[k++] = R[j++]; + } + } + + // Copy the remaining elements of L[], if any + while (i < n1) arr[k++] = L[i++]; + + // Copy the remaining elements of R[], if any + while (j < n2) arr[k++] = R[j++]; + + // Free the temporary arrays + free(L); + free(R); +} + +/** + * Function to perform Merge Sort on an array. + * + * @param arr The array to sort. + * @param left The starting index of the array. + * @param right The ending index of the array. + */ +void merge_sort(int arr[], int left, int right) { + if (left < right) { + // Same as (left + right)/2 but avoids overflow + int mid = left + (right - left) / 2; + + // Sort first and second halves + merge_sort(arr, left, mid); + merge_sort(arr, mid + 1, right); + + merge(arr, left, mid, right); + } +} + +/** + * Main function to demonstrate Merge Sort and measure execution time. + */ +int main() { + int N_values[] = {100000, 200000, 400000, 800000}; + int num_tests = sizeof(N_values) / sizeof(N_values[0]); + + for (int t = 0; t < num_tests; t++) { + int N = N_values[t]; + int *arr = (int *)malloc(N * sizeof(int)); + + // Seed the random number generator + srand(time(NULL)); + + // Fill the array with random integers + for (int i = 0; i < N; i++) { + arr[i] = rand(); + } + + // Measure the start time + clock_t start_time = clock(); + + // Perform Merge Sort + merge_sort(arr, 0, N - 1); + + // Measure the end time + clock_t end_time = clock(); + + // Calculate the elapsed time in seconds + double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC; + + // Verify that the array is sorted + int is_sorted = 1; + for (int i = 1; i < N; i++) { + if (arr[i - 1] > arr[i]) { + is_sorted = 0; + break; + } + } + + // Print the result and time + printf("Merge Sort with N = %d\n", N); + if (is_sorted) + printf("Array is sorted.\n"); + else + printf("Array is NOT sorted.\n"); + printf("Time taken: %f seconds\n\n", time_spent); + + // Free the allocated memory + free(arr); + } + + return 0; +} diff --git a/code/14-quick_sort.c b/code/14-quick_sort.c new file mode 100644 index 0000000..4eb84b9 --- /dev/null +++ b/code/14-quick_sort.c @@ -0,0 +1,105 @@ +#include +#include +#include + +/** + * Function to partition the array on the basis of pivot element. + * + * @param arr The array to partition. + * @param low The starting index. + * @param high The ending index. + * @return The partition index. + */ +int partition(int arr[], int low, int high) { + int pivot = arr[high]; // Choose the last element as pivot + int i = low - 1; // Index of smaller element + + for (int j = low; j <= high - 1; j++) { + // If current element is smaller than or equal to pivot + if (arr[j] <= pivot) { + i++; // Increment index of smaller element + // Swap arr[i] and arr[j] + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + } + // Swap arr[i+1] and arr[high] (or pivot) + int temp = arr[i + 1]; + arr[i + 1] = arr[high]; + arr[high] = temp; + return (i + 1); +} + +/** + * Function to perform Quick Sort on an array. + * + * @param arr The array to sort. + * @param low The starting index. + * @param high The ending index. + */ +void quick_sort(int arr[], int low, int high) { + if (low < high) { + // pi is partitioning index, arr[p] is now at right place + int pi = partition(arr, low, high); + + // Separately sort elements before partition and after partition + quick_sort(arr, low, pi - 1); + quick_sort(arr, pi + 1, high); + } +} + +/** + * Main function to demonstrate Quick Sort and measure execution time. + */ +int main() { + int N_values[] = {100000, 200000, 400000, 800000}; + int num_tests = sizeof(N_values) / sizeof(N_values[0]); + + for (int t = 0; t < num_tests; t++) { + int N = N_values[t]; + int *arr = (int *)malloc(N * sizeof(int)); + + // Seed the random number generator + srand(time(NULL)); + + // Fill the array with random integers + for (int i = 0; i < N; i++) { + arr[i] = rand(); + } + + // Measure the start time + clock_t start_time = clock(); + + // Perform Quick Sort + quick_sort(arr, 0, N - 1); + + // Measure the end time + clock_t end_time = clock(); + + // Calculate the elapsed time in seconds + double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC; + + // Verify that the array is sorted + int is_sorted = 1; + for (int i = 1; i < N; i++) { + if (arr[i - 1] > arr[i]) { + is_sorted = 0; + break; + } + } + + // Print the result and time + printf("Quick Sort with N = %d\n", N); + if (is_sorted) + printf("Array is sorted.\n"); + else + printf("Array is NOT sorted.\n"); + printf("Time taken: %f seconds\n\n", time_spent); + + // Free the allocated memory + free(arr); + } + + return 0; +} diff --git a/code/15-heap_sort.c b/code/15-heap_sort.c new file mode 100644 index 0000000..65e4fad --- /dev/null +++ b/code/15-heap_sort.c @@ -0,0 +1,110 @@ +#include +#include +#include + +/** + * Function to heapify a subtree rooted with node i which is an index in arr[]. + * + * @param arr The array to heapify. + * @param n The size of the heap. + * @param i The index of the root node of the subtree. + */ +void heapify(int arr[], int n, int i) { + int largest = i; // Initialize largest as root + int left = 2 * i + 1; // left = 2*i + 1 + int right = 2 * i + 2; // right = 2*i + 2 + + // If left child exists and is greater than root + if (left < n && arr[left] > arr[largest]) largest = left; + + // If right child exists and is greater than largest so far + if (right < n && arr[right] > arr[largest]) largest = right; + + // If largest is not root + if (largest != i) { + // Swap arr[i] with arr[largest] + int temp = arr[i]; + arr[i] = arr[largest]; + arr[largest] = temp; + + // Recursively heapify the affected sub-tree + heapify(arr, n, largest); + } +} + +/** + * Function to perform Heap Sort on an array. + * + * @param arr The array to sort. + * @param n The size of the array. + */ +void heap_sort(int arr[], int n) { + // Build a maxheap (rearrange array) + for (int i = n / 2 - 1; i >= 0; i--) heapify(arr, n, i); + + // One by one extract elements from heap + for (int i = n - 1; i >= 0; i--) { + // Move current root to end + int temp = arr[0]; + arr[0] = arr[i]; + arr[i] = temp; + + // Call max heapify on the reduced heap + heapify(arr, i, 0); + } +} + +/** + * Main function to demonstrate Heap Sort and measure execution time. + */ +int main() { + int N_values[] = {100000, 200000, 400000, 800000}; + int num_tests = sizeof(N_values) / sizeof(N_values[0]); + + for (int t = 0; t < num_tests; t++) { + int N = N_values[t]; + int *arr = (int *)malloc(N * sizeof(int)); + + // Seed the random number generator + srand(time(NULL)); + + // Fill the array with random integers + for (int i = 0; i < N; i++) { + arr[i] = rand(); + } + + // Measure the start time + clock_t start_time = clock(); + + // Perform Heap Sort + heap_sort(arr, N); + + // Measure the end time + clock_t end_time = clock(); + + // Calculate the elapsed time in seconds + double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC; + + // Verify that the array is sorted + int is_sorted = 1; + for (int i = 1; i < N; i++) { + if (arr[i - 1] > arr[i]) { + is_sorted = 0; + break; + } + } + + // Print the result and time + printf("Heap Sort with N = %d\n", N); + if (is_sorted) + printf("Array is sorted.\n"); + else + printf("Array is NOT sorted.\n"); + printf("Time taken: %f seconds\n\n", time_spent); + + // Free the allocated memory + free(arr); + } + + return 0; +} diff --git a/code/16-counting_sort.c b/code/16-counting_sort.c new file mode 100644 index 0000000..0cee399 --- /dev/null +++ b/code/16-counting_sort.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include + +/** + * Function to perform Counting Sort on an array. + * Assumes that all elements are non-negative integers. + * + * @param arr The array to sort. + * @param n The size of the array. + * @param max_value The maximum possible value in the array. + */ +void counting_sort(int arr[], int n, int max_value) { + int *count = (int *)calloc(max_value + 1, sizeof(int)); + int *output = (int *)malloc(n * sizeof(int)); + + // Store the count of each element + for (int i = 0; i < n; i++) count[arr[i]]++; + + // Change count[i] so that count[i] now contains actual position of this + // element in output array + for (int i = 1; i <= max_value; i++) count[i] += count[i - 1]; + + // Build the output array + for (int i = n - 1; i >= 0; i--) { + output[count[arr[i]] - 1] = arr[i]; + count[arr[i]]--; + } + + // Copy the output array to arr[] + memcpy(arr, output, n * sizeof(int)); + + // Free allocated memory + free(count); + free(output); +} + +/** + * Main function to demonstrate Counting Sort and measure execution time. + */ +int main() { + int N_values[] = {100000, 200000, 400000, 800000}; + int num_tests = sizeof(N_values) / sizeof(N_values[0]); + int max_value = 1000000; // Define a maximum value for elements in the array + + for (int t = 0; t < num_tests; t++) { + int N = N_values[t]; + int *arr = (int *)malloc(N * sizeof(int)); + + // Seed the random number generator + srand(time(NULL)); + + // Fill the array with random integers between 0 and max_value + for (int i = 0; i < N; i++) { + arr[i] = rand() % (max_value + 1); + } + + // Measure the start time + clock_t start_time = clock(); + + // Perform Counting Sort + counting_sort(arr, N, max_value); + + // Measure the end time + clock_t end_time = clock(); + + // Calculate the elapsed time in seconds + double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC; + + // Verify that the array is sorted + int is_sorted = 1; + for (int i = 1; i < N; i++) { + if (arr[i - 1] > arr[i]) { + is_sorted = 0; + break; + } + } + + // Print the result and time + printf("Counting Sort with N = %d\n", N); + if (is_sorted) + printf("Array is sorted.\n"); + else + printf("Array is NOT sorted.\n"); + printf("Time taken: %f seconds\n\n", time_spent); + + // Free the allocated memory + free(arr); + } + + return 0; +} diff --git a/code/17-radix_sort.c b/code/17-radix_sort.c new file mode 100644 index 0000000..31397e7 --- /dev/null +++ b/code/17-radix_sort.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include + +#define BASE 10 // Base of numeral system (decimal) + +/** + * Function to get the maximum value in an array. + * + * @param arr The array to search. + * @param n The size of the array. + * @return The maximum value in the array. + */ +int get_max(int arr[], int n) { + int max = arr[0]; + for (int i = 1; i < n; i++) + if (arr[i] > max) max = arr[i]; + return max; +} + +/** + * Function to perform Counting Sort based on a specific digit represented by + * exp. + * + * @param arr The array to sort. + * @param n The size of the array. + * @param exp The exponent representing the digit position. + */ +void counting_sort_by_digit(int arr[], int n, int exp) { + int *output = (int *)malloc(n * sizeof(int)); + int count[BASE] = {0}; + + // Store count of occurrences in count[] + for (int i = 0; i < n; i++) count[(arr[i] / exp) % BASE]++; + + // Change count[i] so that count[i] now contains actual position of this digit + // in output[] + for (int i = 1; i < BASE; i++) count[i] += count[i - 1]; + + // Build the output array + for (int i = n - 1; i >= 0; i--) { + int digit = (arr[i] / exp) % BASE; + output[count[digit] - 1] = arr[i]; + count[digit]--; + } + + // Copy the output array to arr[] + memcpy(arr, output, n * sizeof(int)); + + // Free allocated memory + free(output); +} + +/** + * Function to perform Radix Sort on an array. + * + * @param arr The array to sort. + * @param n The size of the array. + */ +void radix_sort(int arr[], int n) { + // Find the maximum number to know the number of digits + int max = get_max(arr, n); + + // Do counting sort for every digit + for (int exp = 1; max / exp > 0; exp *= BASE) + counting_sort_by_digit(arr, n, exp); +} + +/** + * Main function to demonstrate Radix Sort and measure execution time. + */ +int main() { + int N_values[] = {100000, 200000, 400000, 800000}; + int num_tests = sizeof(N_values) / sizeof(N_values[0]); + int max_value = 1000000; // Define a maximum value for elements in the array + + for (int t = 0; t < num_tests; t++) { + int N = N_values[t]; + int *arr = (int *)malloc(N * sizeof(int)); + + // Seed the random number generator + srand(time(NULL)); + + // Fill the array with random integers between 0 and max_value + for (int i = 0; i < N; i++) { + arr[i] = rand() % (max_value + 1); + } + + // Measure the start time + clock_t start_time = clock(); + + // Perform Radix Sort + radix_sort(arr, N); + + // Measure the end time + clock_t end_time = clock(); + + // Calculate the elapsed time in seconds + double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC; + + // Verify that the array is sorted + int is_sorted = 1; + for (int i = 1; i < N; i++) { + if (arr[i - 1] > arr[i]) { + is_sorted = 0; + break; + } + } + + // Print the result and time + printf("Radix Sort with N = %d\n", N); + if (is_sorted) + printf("Array is sorted.\n"); + else + printf("Array is NOT sorted.\n"); + printf("Time taken: %f seconds\n\n", time_spent); + + // Free the allocated memory + free(arr); + } + + return 0; +} diff --git a/code/10-recursion_palindrome.c b/code/18-recursion_palindrome.c similarity index 100% rename from code/10-recursion_palindrome.c rename to code/18-recursion_palindrome.c diff --git a/code/11-divide_and_conquer_power.c b/code/19-divide_and_conquer_power.c similarity index 100% rename from code/11-divide_and_conquer_power.c rename to code/19-divide_and_conquer_power.c