├── 0-O ├── 1-O ├── 101-O ├── 102-O ├── 105-O ├── 2-O ├── 107-O ├── 3-O ├── 103-O ├── 104-O ├── 106-O ├── swap.c ├── pivot.c ├── 0-bubble_sort.c ├── 100-shell_sort.c ├── _partition.c ├── deck.h ├── 2-selection_sort.c ├── sort.h ├── 1-insertion_sort_list.c ├── 3-quick_sort.c ├── 102-counting_sort.c ├── 107-quick_sort_hoare.c ├── 104-heap_sort.c ├── 105-radix_sort.c ├── 106-bitonic_sort.c ├── 103-merge_sort.c ├── 101-cocktail_sort_list.c ├── 1000-sort_deck.c └── README.md /0-O: -------------------------------------------------------------------------------- 1 | O(n) 2 | O(n^2) 3 | O(n^2) 4 | -------------------------------------------------------------------------------- /1-O: -------------------------------------------------------------------------------- 1 | O(n) 2 | O(n^2) 3 | O(n^2) 4 | -------------------------------------------------------------------------------- /101-O: -------------------------------------------------------------------------------- 1 | O(n) 2 | O(n^2) 3 | O(n^2) 4 | -------------------------------------------------------------------------------- /102-O: -------------------------------------------------------------------------------- 1 | O(n+k) 2 | O(n+k) 3 | O(n+k) 4 | -------------------------------------------------------------------------------- /105-O: -------------------------------------------------------------------------------- 1 | O(nk) 2 | O(nk) 3 | O(nk) 4 | -------------------------------------------------------------------------------- /2-O: -------------------------------------------------------------------------------- 1 | O(n^2) 2 | O(n^2) 3 | O(n^2) 4 | -------------------------------------------------------------------------------- /107-O: -------------------------------------------------------------------------------- 1 | O(nlog(n)) 2 | O(nlog(n)) 3 | O(n^2) 4 | -------------------------------------------------------------------------------- /3-O: -------------------------------------------------------------------------------- 1 | O(nlog(n)) 2 | O(nlog(n)) 3 | O(n^2) 4 | -------------------------------------------------------------------------------- /103-O: -------------------------------------------------------------------------------- 1 | O(nlog(n)) 2 | O(nlog(n)) 3 | O(nlog(n)) 4 | -------------------------------------------------------------------------------- /104-O: -------------------------------------------------------------------------------- 1 | O(nlog(n)) 2 | O(nlog(n)) 3 | O(nlog(n)) 4 | -------------------------------------------------------------------------------- /106-O: -------------------------------------------------------------------------------- 1 | O(log^2(n)) 2 | O(log^2(n)) 3 | O(log^2(n)) 4 | -------------------------------------------------------------------------------- /swap.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | /** 4 | * swap - Swaps the values of two integers 5 | * 6 | * @a: Pointer to the first integer 7 | * @b: Pointer to the second integer 8 | */ 9 | void swap(int *a, int *b) 10 | { 11 | int temp; 12 | 13 | temp = *a; 14 | *a = *b; 15 | *b = temp; 16 | } 17 | -------------------------------------------------------------------------------- /pivot.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | /** 4 | * qs - sorts an array of integers recursively 5 | * @array: array to sort 6 | * @first: first position 7 | * @last: last position 8 | * @size: array size 9 | */ 10 | void qs(int *array, int first, int last, size_t size) 11 | { 12 | int pivot; 13 | 14 | if (first < last) 15 | { 16 | pivot = partition(array, first, last, size); 17 | qs(array, first, pivot - 1, size); 18 | qs(array, pivot + 1, last, size); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /0-bubble_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | /** 4 | * bubble_sort - sort list with bubble 5 | * @array: The array to be printed 6 | * @size: Number of elements in @array 7 | */ 8 | void bubble_sort(int *array, size_t size) 9 | { 10 | size_t i = 0, j = size; 11 | int tmp, sorted; 12 | 13 | if (array == NULL) 14 | return; 15 | for (j = size; j > 0; j--) 16 | { 17 | sorted = 0; 18 | for (i = 0; i < size - 1; i++) 19 | { 20 | if (array[i] > array[i + 1]) 21 | { 22 | tmp = array[i]; 23 | array[i] = array[i + 1]; 24 | array[i + 1] = tmp; 25 | print_array(array, size); 26 | sorted = 1; 27 | } 28 | } 29 | if (sorted == 0) 30 | { 31 | break; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /100-shell_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | /** 4 | * shell_sort - Shell sort algorithm 5 | * @array: unsorted data 6 | * @size: large of array 7 | * Return: Nothing 8 | */ 9 | void shell_sort(int *array, size_t size) 10 | { 11 | int tmp; 12 | size_t j, gap, n; 13 | 14 | gap = 1; 15 | if (!array || size < 2) 16 | return; 17 | /* Create Knuth sequence */ 18 | while (gap < size / 3) 19 | gap = gap * 3 + 1; 20 | while (gap > 0) 21 | { 22 | for (j = gap; j < size; j += 1) 23 | { 24 | tmp = array[j]; 25 | for (n = j; n >= gap && tmp < array[n - gap]; n -= gap) 26 | array[n] = array[n - gap]; 27 | array[n] = tmp; 28 | } 29 | /* decreasing the interval */ 30 | gap /= 3; 31 | print_array(array, size); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /_partition.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | /** 4 | * partition - array partition 5 | * @array: array to sort 6 | * @first: first position 7 | * @last: last position 8 | * @size: array size 9 | * Return: int pivot index 10 | */ 11 | int partition(int *array, int first, int last, size_t size) 12 | { 13 | int i = first - 1, aux, j; 14 | 15 | for (j = first; j <= last - 1; j++) 16 | { 17 | if (array[j] < array[last]) 18 | { 19 | i++; 20 | if (i < j) 21 | { 22 | aux = array[i]; 23 | array[i] = array[j]; 24 | array[j] = aux; 25 | print_array(array, size); 26 | } 27 | } 28 | } 29 | if (array[i + 1] > array[last]) 30 | { 31 | aux = array[i + 1]; 32 | array[i + 1] = array[last]; 33 | array[last] = aux; 34 | print_array(array, size); 35 | } 36 | 37 | return (i + 1); 38 | } 39 | -------------------------------------------------------------------------------- /deck.h: -------------------------------------------------------------------------------- 1 | #ifndef _DECK_H_ 2 | #define _DECK_H_ 3 | #include 4 | #include 5 | /** 6 | * enum kind_e - kinds in the deck 7 | * 8 | * @SPADE: 0 9 | * @HEART: 1 10 | * @CLUB: 2 11 | * @DIAMOND: 3 12 | */ 13 | typedef enum kind_e 14 | { 15 | SPADE = 0, 16 | HEART, 17 | CLUB, 18 | DIAMOND 19 | } kind_t; 20 | 21 | /** 22 | * struct card_s - Playing card 23 | * 24 | * @value: Value of the card 25 | * From "Ace" to "King" 26 | * @kind: Kind of the card 27 | */ 28 | typedef struct card_s 29 | { 30 | const char *value; 31 | const kind_t kind; 32 | } card_t; 33 | 34 | /** 35 | * struct deck_node_s - Deck of card 36 | * 37 | * @card: Pointer to the card of the node 38 | * @prev: Pointer to the previous node of the list 39 | * @next: Pointer to the next node of the list 40 | */ 41 | typedef struct deck_node_s 42 | { 43 | const card_t *card; 44 | struct deck_node_s *prev; 45 | struct deck_node_s *next; 46 | } deck_node_t; 47 | void sort_deck(deck_node_t **deck); 48 | #endif 49 | -------------------------------------------------------------------------------- /2-selection_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | /** 4 | * swap - Swap two integers in an array. 5 | * @a: The first integer to swap. 6 | * @b: The second integer to swap. 7 | */ 8 | void swap(int *a, int *b) 9 | { 10 | int tmp; 11 | 12 | tmp = *a; 13 | *a = *b; 14 | *b = tmp; 15 | } 16 | 17 | /** 18 | * selection_sort - Sort an array of integers in ascending order 19 | * using the selection sort algorithm. 20 | * @array: An array of integers. 21 | * @size: The size of the array. 22 | * 23 | * Description: Prints the array after each swap. 24 | */ 25 | void selection_sort(int *array, size_t size) 26 | { 27 | int *first_min; 28 | size_t i, j; 29 | 30 | if (array == NULL || size < 2) 31 | return; 32 | 33 | for (i = 0; i < size - 1; i++) 34 | { 35 | first_min = array + i; 36 | for (j = i + 1; j < size; j++) 37 | { 38 | first_min = (array[j] < *first_min) ? (array + j) : first_min; 39 | } 40 | if ((array + i) != first_min) 41 | { 42 | swap(array + i, first_min); 43 | print_array(array, size); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /sort.h: -------------------------------------------------------------------------------- 1 | #ifndef SORT_H 2 | #define SORT_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * struct listint_s - Doubly linked list node 10 | * 11 | * @n: Integer stored in the node 12 | * @prev: Pointer to the previous element of the list 13 | * @next: Pointer to the next element of the list 14 | */ 15 | typedef struct listint_s 16 | { 17 | const int n; 18 | struct listint_s *prev; 19 | struct listint_s *next; 20 | } listint_t; 21 | 22 | void bubble_sort(int *array, size_t size); 23 | void print_array(const int *array, size_t size); 24 | void print_list(const listint_t *list); 25 | listint_t *swap_node(listint_t *node, listint_t **list); 26 | void insertion_sort_list(listint_t **list); 27 | void selection_sort(int *array, size_t size); 28 | void quick_sort(int *array, size_t size); 29 | void shell_sort(int *array, size_t size); 30 | void cocktail_sort_list(listint_t **list); 31 | void counting_sort(int *array, size_t size); 32 | void merge_sort(int *array, size_t size); 33 | void heap_sort(int *array, size_t size); 34 | void radix_sort(int *array, size_t size); 35 | void bitonic_sort(int *array, size_t size); 36 | void quick_sort_hoare(int *array, size_t size); 37 | void swap(int *a, int *b); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /1-insertion_sort_list.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | void swap_nodes(listint_t **head, listint_t **n1, listint_t *n2); 4 | 5 | /** 6 | * insertion_sort_list - A function that sorts a doubly linked 7 | * list of integers in ascending order 8 | * @list: A pointer to the head of a doubly-linked list of integers 9 | * Description: Prints the list after each swap 10 | * Return: Nothing 11 | */ 12 | void insertion_sort_list(listint_t **list) 13 | { 14 | listint_t *current, *prevoius; 15 | 16 | if (list == NULL || *list == NULL || (*list)->next == NULL) 17 | return; 18 | 19 | for (current = (*list)->next; current != NULL; current = current->next) 20 | { 21 | prevoius = current->prev; 22 | while (prevoius != NULL && current->n < prevoius->n) 23 | { 24 | swap_nodes(list, &prevoius, current); 25 | print_list((const listint_t *)*list); 26 | } 27 | } 28 | } 29 | 30 | /** 31 | * swap_nodes - Swap two nodes in a listint_t doubly-linked list 32 | * @head: A pointer to the head of the doubly-linked list 33 | * @n1: A pointer to the first node to swap 34 | * @n2: The second node to swap 35 | * 36 | * Return: Nothing 37 | */ 38 | void swap_nodes(listint_t **head, listint_t **n1, listint_t *n2) 39 | { 40 | (*n1)->next = n2->next; 41 | if (n2->next != NULL) 42 | n2->next->prev = *n1; 43 | n2->prev = (*n1)->prev; 44 | n2->next = *n1; 45 | if ((*n1)->prev != NULL) 46 | (*n1)->prev->next = n2; 47 | else 48 | *head = n2; 49 | (*n1)->prev = n2; 50 | *n1 = n2->prev; 51 | } 52 | -------------------------------------------------------------------------------- /3-quick_sort.c: -------------------------------------------------------------------------------- 1 | 2 | #include "sort.h" 3 | 4 | 5 | /** 6 | * _partition - array partition 7 | * @array: array to sort 8 | * @low: first index 9 | * @high: last index 10 | * @size: array size 11 | * Return: int pivot index 12 | */ 13 | int _partition(int *array, int low, int high, size_t size) 14 | { 15 | int i = low - 1, tmp, j; 16 | 17 | for (j = low; j <= high - 1; j++) 18 | { 19 | if (array[j] < array[high]) 20 | { 21 | i++; 22 | if (i < j) 23 | { 24 | tmp = array[i]; 25 | array[i] = array[j]; 26 | array[j] = tmp; 27 | print_array(array, size); 28 | } 29 | } 30 | } 31 | if (array[i + 1] > array[high]) 32 | { 33 | tmp = array[i + 1]; 34 | array[i + 1] = array[high]; 35 | array[high] = tmp; 36 | print_array(array, size); 37 | } 38 | 39 | return (i + 1); 40 | } 41 | 42 | /** 43 | * qs - sorts an array of integers recursively 44 | * @array: array to sort 45 | * @low: first index 46 | * @high: last index 47 | * @size: array size 48 | */ 49 | void qs(int *array, int low, int high, size_t size) 50 | { 51 | int pivot; 52 | 53 | if (low < high) 54 | { 55 | pivot = _partition(array, low, high, size); 56 | qs(array, low, pivot - 1, size); 57 | qs(array, pivot + 1, high, size); 58 | } 59 | } 60 | 61 | /** 62 | * quick_sort - sorts an array of integers using the Quick 63 | * sort algorithm in ascending order 64 | * @array: array to sort 65 | * @size: array size 66 | */ 67 | void quick_sort(int *array, size_t size) 68 | { 69 | qs(array, 0, size - 1, size); 70 | } 71 | -------------------------------------------------------------------------------- /102-counting_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | /** 4 | * get_max - Get the maximum value in an array of integers. 5 | * @array: An array of integers. 6 | * @size: The size of the array. 7 | * 8 | * Return: The maximum integer in the array. 9 | */ 10 | int get_max(int *array, int size) 11 | { 12 | int max, i; 13 | 14 | for (max = array[0], i = 1; i < size; i++) 15 | { 16 | if (array[i] > max) 17 | max = array[i]; 18 | } 19 | 20 | return (max); 21 | } 22 | 23 | /** 24 | * counting_sort - Sort an array of integers in ascending order 25 | * using the counting sort algorithm. 26 | * @array: An array of integers. 27 | * @size: The size of the array. 28 | * 29 | * Description: Prints the counting array after setting it up. 30 | */ 31 | void counting_sort(int *array, size_t size) 32 | { 33 | int *count, *sorted, max, i; 34 | 35 | if (array == NULL || size < 2) 36 | return; 37 | 38 | sorted = malloc(sizeof(int) * size); 39 | if (sorted == NULL) 40 | return; 41 | max = get_max(array, size); 42 | count = malloc(sizeof(int) * (max + 1)); 43 | if (count == NULL) 44 | { 45 | free(sorted); 46 | return; 47 | } 48 | 49 | for (i = 0; i < (max + 1); i++) 50 | count[i] = 0; 51 | for (i = 0; i < (int)size; i++) 52 | count[array[i]] += 1; 53 | for (i = 0; i < (max + 1); i++) 54 | count[i] += count[i - 1]; 55 | print_array(count, max + 1); 56 | 57 | for (i = 0; i < (int)size; i++) 58 | { 59 | sorted[count[array[i]] - 1] = array[i]; 60 | count[array[i]] -= 1; 61 | } 62 | 63 | for (i = 0; i < (int)size; i++) 64 | array[i] = sorted[i]; 65 | 66 | free(sorted); 67 | free(count); 68 | } 69 | -------------------------------------------------------------------------------- /107-quick_sort_hoare.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | /** 4 | * partition - sorts a partition of data in relation to a pivot 5 | * 6 | * @array: data to sort 7 | * @min: Left wall 8 | * @max: right wall 9 | * @size: size of data 10 | * 11 | * Return: New Pivot 12 | */ 13 | int partition(int *array, int min, int max, size_t size) 14 | { 15 | int tmp, i, j, pivot = array[max]; 16 | 17 | for (i = min, j = max; 1; i++, j--) 18 | { 19 | while (array[i] < pivot) 20 | i++; 21 | 22 | while (array[j] > pivot) 23 | j--; 24 | 25 | if (i >= j) 26 | return (i); 27 | tmp = array[i]; 28 | array[i] = array[j]; 29 | array[j] = tmp; 30 | print_array(array, size); 31 | } 32 | } 33 | 34 | /** 35 | * quicksort - sorts an array of integers in ascending order using the 36 | * Quick sort algorithm Lomuto partition scheme 37 | * 38 | * @array: data to sort 39 | * @min: Left wall 40 | * @max: right wall 41 | * @size: size of data 42 | * 43 | * Return: No Return 44 | */ 45 | void quicksort(int *array, int min, int max, size_t size) 46 | { 47 | int p; 48 | 49 | if (min < max) 50 | { 51 | p = partition(array, min, max, size); 52 | quicksort(array, min, p - 1, size); 53 | quicksort(array, p, max, size); 54 | } 55 | } 56 | 57 | /** 58 | * quick_sort_hoare - sorts an array of integers in ascending order using the 59 | * Quick sort algorithm Hoare partition scheme 60 | * 61 | * @array: data to sort 62 | * @size: size of data 63 | * 64 | * Return: No Return 65 | */ 66 | void quick_sort_hoare(int *array, size_t size) 67 | { 68 | if (!array || size < 2) 69 | return; 70 | 71 | quicksort(array, 0, size - 1, size); 72 | } 73 | -------------------------------------------------------------------------------- /104-heap_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sort.h" 3 | #define getParent(i) (((i) - 1) / 2) 4 | #define getLeft(i) (2 * (i) + 1) 5 | #define getRight(i) (2 * (i) + 2) 6 | void sift_down(int *array, size_t size, size_t index, size_t nth); 7 | void heap_sort(int *array, size_t size); 8 | /** 9 | * heap_sort - use heap sort 10 | * @array: array to sort 11 | * @size: size of array 12 | */ 13 | void heap_sort(int *array, size_t size) 14 | { 15 | size_t node, sorted; 16 | if (array == NULL || size < 2) 17 | return; 18 | for (node = getParent(size - 1); node != SIZE_MAX; node--) 19 | sift_down(array, size, node, size - 1); 20 | for (sorted = size - 1; sorted > 1; sorted--) 21 | { 22 | array[0] ^= array[sorted]; 23 | array[sorted] ^= array[0]; 24 | array[0] ^= array[sorted]; 25 | print_array(array, size); 26 | sift_down(array, size, 0, sorted - 1); 27 | } 28 | array[0] ^= array[1]; 29 | array[1] ^= array[0]; 30 | array[0] ^= array[1]; 31 | print_array(array, size); 32 | } 33 | /** 34 | * sift_down - sift_down 35 | * @array: array containing heap 36 | * @size: total size of array 37 | * @index: index of index node of heap 38 | * @nth: index of nth node in heap to examine 39 | */ 40 | void sift_down(int *array, size_t size, size_t index, size_t nth) 41 | { 42 | size_t largest, left, right; 43 | do { 44 | left = getLeft(index); 45 | right = getRight(index); 46 | largest = index; 47 | if (right <= nth && array[right] > array[index]) 48 | largest = right; 49 | if (array[left] > array[largest]) 50 | largest = left; 51 | if (index == largest) 52 | return; 53 | array[index] ^= array[largest]; 54 | array[largest] ^= array[index]; 55 | array[index] ^= array[largest]; 56 | print_array(array, size); 57 | index = largest; 58 | } while (getLeft(index) <= nth); 59 | } 60 | -------------------------------------------------------------------------------- /105-radix_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | void radix_counting_sort(int *array, size_t size, int sig, int *buff); 4 | void radix_sort(int *array, size_t size); 5 | int get_max(int *array, int size); 6 | 7 | /** 8 | * radix_sort - A function that sorts an array of integers in ascending 9 | * order using the Radix sort algorithm 10 | * @array: An array of integers 11 | * @size: The size of the array 12 | * 13 | * Return: Nothing 14 | */ 15 | void radix_sort(int *array, size_t size) 16 | { 17 | int max, sig, *buff; 18 | 19 | if (array == NULL || size < 2) 20 | return; 21 | buff = malloc(sizeof(int) * size); 22 | if (buff == NULL) 23 | return; 24 | max = get_max(array, size); 25 | for (sig = 1; max / sig > 0; sig *= 10) 26 | { 27 | radix_counting_sort(array, size, sig, buff); 28 | print_array(array, size); 29 | } 30 | free(buff); 31 | } 32 | 33 | /** 34 | * radix_counting_sort - Sort the significant digits of an array of integers 35 | * in ascending order using the counting sort algorithm 36 | * @array: An array of integers 37 | * @size: The size of the array 38 | * @sig: The significant digit to sort on 39 | * @buff: A buffer to store the sorted array 40 | * 41 | * Return: Nothing 42 | */ 43 | void radix_counting_sort(int *array, size_t size, int sig, int *buff) 44 | { 45 | int count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 46 | size_t i; 47 | 48 | for (i = 0; i < size; i++) 49 | count[(array[i] / sig) % 10] += 1; 50 | 51 | for (i = 0; i < 10; i++) 52 | count[i] += count[i - 1]; 53 | 54 | for (i = size - 1; (int)i >= 0; i--) 55 | { 56 | buff[count[(array[i] / sig) % 10] - 1] = array[i]; 57 | count[(array[i] / sig) % 10] -= 1; 58 | } 59 | 60 | for (i = 0; i < size; i++) 61 | array[i] = buff[i]; 62 | } 63 | 64 | /** 65 | * get_max - Get the maximum value in an array of integers 66 | * @array: An array of integers 67 | * @size: The size of the array 68 | * Return: The maximum integer in the array 69 | */ 70 | int get_max(int *array, int size) 71 | { 72 | int max, i; 73 | 74 | for (max = array[0], i = 1; i < size; i++) 75 | { 76 | if (array[i] > max) 77 | max = array[i]; 78 | } 79 | 80 | return (max); 81 | } 82 | -------------------------------------------------------------------------------- /106-bitonic_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | /** 4 | * swap - swap an intger 5 | * @a: address of first value 6 | * @b: address of second value 7 | * 8 | * Return: void 9 | */ 10 | void swap(int *a, int *b) 11 | { 12 | if (*a != *b) 13 | { 14 | *a = *a + *b; 15 | *b = *a - *b; 16 | *a = *a - *b; 17 | } 18 | } 19 | 20 | /** 21 | * bitonic_compare - compares bitonically 22 | * @up: true if UP sorting 23 | * @array: the array pointer 24 | * @start: the start index 25 | * @end: the stop index 26 | */ 27 | void bitonic_compare(int up, int *array, size_t start, size_t end) 28 | { 29 | size_t half = (end - start + 1) / 2, i; 30 | 31 | for (i = start; i < start + half; i++) 32 | if ((array[i] > array[i + half]) == up) 33 | swap(&array[i], &array[i + half]); 34 | } 35 | 36 | /** 37 | * bitonic_merge - merges bitonically 38 | * @up: true if UP sorting 39 | * @array: the array pointer 40 | * @start: the start index 41 | * @end: the stop index 42 | */ 43 | void bitonic_merge(int up, int *array, size_t start, size_t end) 44 | { 45 | size_t mid = (start + end) / 2; 46 | 47 | if (end - start < 1) 48 | return; 49 | bitonic_compare(up, array, start, end); 50 | bitonic_merge(up, array, start, mid); 51 | bitonic_merge(up, array, mid + 1, end); 52 | } 53 | 54 | /** 55 | * _bitonic_sort - sorts bitonically by recursion 56 | * @up: true if UP sorting 57 | * @array: the array pointer 58 | * @size: the length of the array 59 | * @start: the start index 60 | * @end: the stop index 61 | */ 62 | void _bitonic_sort(int up, int *array, size_t size, size_t start, size_t end) 63 | { 64 | size_t mid = (start + end) / 2; 65 | 66 | if (end - start < 1) 67 | return; 68 | printf("Merging [%lu/%lu] (%s):\n", end - start + 1, size, 69 | up ? "UP" : "DOWN"); 70 | print_array(array + start, end - start + 1); 71 | _bitonic_sort(1, array, size, start, mid); 72 | _bitonic_sort(0, array, size, mid + 1, end); 73 | bitonic_merge(up, array, start, end); 74 | printf("Result [%lu/%lu] (%s):\n", end - start + 1, size, 75 | up ? "UP" : "DOWN"); 76 | print_array(array + start, end - start + 1); 77 | } 78 | 79 | /** 80 | * bitonic_sort - sorts bitonically 81 | * @array: the array pointer 82 | * @size: the length of the array 83 | */ 84 | void bitonic_sort(int *array, size_t size) 85 | { 86 | if (!array || size < 2) 87 | return; 88 | 89 | _bitonic_sort(1, array, size, 0, size - 1); 90 | } 91 | -------------------------------------------------------------------------------- /103-merge_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | void merge_subarr(int *subarr, int *buff, size_t front, size_t mid, 4 | size_t back); 5 | void merge_sort_recursive(int *subarr, int *buff, size_t front, size_t back); 6 | 7 | /** 8 | * merge_sort - A function that sorts an array of integers in ascending 9 | * order using the merge sort algorithm 10 | * @array: An array of integers 11 | * @size: The size of the array. 12 | * 13 | * Return: Nothing 14 | */ 15 | void merge_sort(int *array, size_t size) 16 | { 17 | int *buff; 18 | 19 | if (array == NULL || size < 2) 20 | return; 21 | buff = malloc(sizeof(int) * size); 22 | if (buff == NULL) 23 | return; 24 | merge_sort_recursive(array, buff, 0, size); 25 | free(buff); 26 | } 27 | 28 | /** 29 | * merge_sort_recursive - Merge sort algorithm through recursive 30 | * @subarr: A subarray of an array of integers to sort 31 | * @buff: A buffer to store the sorted result 32 | * @front: The front index of the subarray 33 | * @back: The back index of the subarray 34 | * 35 | * Return: Nothing 36 | */ 37 | void merge_sort_recursive(int *subarr, int *buff, size_t front, size_t back) 38 | { 39 | size_t mid; 40 | 41 | if (back - front > 1) 42 | { 43 | mid = front + (back - front) / 2; 44 | merge_sort_recursive(subarr, buff, front, mid); 45 | merge_sort_recursive(subarr, buff, mid, back); 46 | merge_subarr(subarr, buff, front, mid, back); 47 | } 48 | } 49 | 50 | /** 51 | * merge_subarr - Sort a subarray 52 | * @subarr: A subarray of an array of integers to sort 53 | * @buff: A buffer to store the sorted subarray 54 | * @front: The front index of the array 55 | * @mid: The middle index of the array 56 | * @back: The back index of the array 57 | * 58 | * Return: Nothing 59 | */ 60 | void merge_subarr(int *subarr, int *buff, size_t front, size_t mid, 61 | size_t back) 62 | { 63 | size_t i, j, k = 0; 64 | 65 | printf("Merging...\n[left]: "); 66 | print_array(subarr + front, mid - front); 67 | 68 | printf("[right]: "); 69 | print_array(subarr + mid, back - mid); 70 | 71 | for (i = front, j = mid; i < mid && j < back; k++) 72 | buff[k] = (subarr[i] < subarr[j]) ? subarr[i++] : subarr[j++]; 73 | for (; i < mid; i++) 74 | buff[k++] = subarr[i]; 75 | for (; j < back; j++) 76 | buff[k++] = subarr[j]; 77 | for (i = front, k = 0; i < back; i++) 78 | subarr[i] = buff[k++]; 79 | 80 | printf("[Done]: "); 81 | print_array(subarr + front, back - front); 82 | } 83 | 84 | -------------------------------------------------------------------------------- /101-cocktail_sort_list.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | void swap_node_ahead(listint_t **head, listint_t **tail, listint_t **shaker); 4 | void swap_node_behind(listint_t **head, listint_t **tail, listint_t **shaker); 5 | 6 | /** 7 | * cocktail_sort_list - A function that sorts a doubly linked list 8 | * of integers in ascending order 9 | * @list: A pointer to the head of a listint_t doubly-linked list 10 | * 11 | * Return: Nothing 12 | */ 13 | void cocktail_sort_list(listint_t **list) 14 | { 15 | listint_t *tail, *shaker; 16 | int flag = 0; 17 | 18 | if (list == NULL || *list == NULL || (*list)->next == NULL) 19 | return; 20 | 21 | for (tail = *list; tail->next != NULL;) 22 | tail = tail->next; 23 | 24 | while (flag == 0) 25 | { 26 | flag = 1; 27 | for (shaker = *list; shaker != tail; shaker = shaker->next) 28 | { 29 | if (shaker->n > shaker->next->n) 30 | { 31 | swap_node_ahead(list, &tail, &shaker); 32 | print_list((const listint_t *)*list); 33 | flag = 0; 34 | } 35 | } 36 | for (shaker = shaker->prev; shaker != *list; shaker = shaker->prev) 37 | { 38 | if (shaker->n < shaker->prev->n) 39 | { 40 | swap_node_behind(list, &tail, &shaker); 41 | print_list((const listint_t *)*list); 42 | flag = 0; 43 | } 44 | } 45 | } 46 | } 47 | 48 | /** 49 | * swap_node_ahead - Swap a node in a listint_t doubly-linked list of ahead 50 | * @head: A pointer to the head of a doubly-linked list of integers 51 | * @tail: A pointer to the tail of the doubly-linked list 52 | * @shaker: A pointer to the current swapping node of the cocktail shaker algo 53 | * 54 | * Return: Nothing 55 | */ 56 | void swap_node_ahead(listint_t **head, listint_t **tail, listint_t **shaker) 57 | { 58 | listint_t *tmp = (*shaker)->next; 59 | 60 | if ((*shaker)->prev != NULL) 61 | (*shaker)->prev->next = tmp; 62 | else 63 | *head = tmp; 64 | tmp->prev = (*shaker)->prev; 65 | (*shaker)->next = tmp->next; 66 | if (tmp->next != NULL) 67 | tmp->next->prev = *shaker; 68 | else 69 | *tail = *shaker; 70 | (*shaker)->prev = tmp; 71 | tmp->next = *shaker; 72 | *shaker = tmp; 73 | } 74 | 75 | /** 76 | * swap_node_behind - Swap a node in a listint_t doubly-linked behind 77 | * @head: A pointer to the head of a doubly-linked list of integers 78 | * @tail: A pointer to the tail of the doubly-linked list 79 | * @shaker: A pointer to the current swapping node of the cocktail shaker algo 80 | * 81 | * Return: Nothing 82 | */ 83 | void swap_node_behind(listint_t **head, listint_t **tail, listint_t **shaker) 84 | { 85 | listint_t *tmp = (*shaker)->prev; 86 | 87 | if ((*shaker)->next != NULL) 88 | (*shaker)->next->prev = tmp; 89 | else 90 | *tail = tmp; 91 | tmp->next = (*shaker)->next; 92 | (*shaker)->prev = tmp->prev; 93 | if (tmp->prev != NULL) 94 | tmp->prev->next = *shaker; 95 | else 96 | *head = *shaker; 97 | (*shaker)->next = tmp; 98 | tmp->prev = *shaker; 99 | *shaker = tmp; 100 | } 101 | -------------------------------------------------------------------------------- /1000-sort_deck.c: -------------------------------------------------------------------------------- 1 | #include "deck.h" 2 | /** 3 | * aux_num_fun - turn into integer card value 4 | * @head_tmp1: pointer to the list 5 | * Return: integer rep 6 | **/ 7 | int aux_num_fun(deck_node_t *head_tmp1) 8 | { 9 | int aux_num, j; 10 | int num[13] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; 11 | char val[13] = {'A', '2', '3', '4', '5', '6', '7', 12 | '8', '9', '1', 'J', 'Q', 'K'}; 13 | 14 | for (j = 0; j < 13; j++) 15 | { 16 | if (head_tmp1->card->value[0] == val[j]) 17 | aux_num = num[j]; 18 | } 19 | 20 | return (aux_num); 21 | } 22 | /** 23 | * num_sort - sorts a doubly linked list of integers, 4 stages 24 | * @list: pointer to the list head 25 | * Return: no return 26 | **/ 27 | void num_sort(deck_node_t **list) 28 | { 29 | deck_node_t *head_tmp1, *head_tmp2, *aux1, *aux2; 30 | int flag = 0, i, aux_num1, aux_num2; 31 | unsigned int k; 32 | 33 | head_tmp1 = *list; 34 | head_tmp2 = *list; 35 | for (i = 0; i < 4; i++) 36 | { k = head_tmp1->card->kind; 37 | while (head_tmp1->next && head_tmp1->next->card->kind == k) 38 | { 39 | aux_num1 = aux_num_fun(head_tmp1); 40 | aux_num2 = aux_num_fun(head_tmp1->next); 41 | flag = 0; 42 | head_tmp2 = head_tmp1; 43 | while (head_tmp2 && head_tmp2->card->kind == k && aux_num1 > aux_num2) 44 | { 45 | aux1 = head_tmp2; 46 | aux2 = head_tmp2->next; 47 | aux1->next = aux2->next; 48 | if (aux2->next) 49 | aux2->next->prev = aux1; 50 | aux2->prev = aux1->prev; 51 | aux2->next = aux1; 52 | aux1->prev = aux2; 53 | if (aux2->prev) 54 | aux2->prev->next = aux2; 55 | head_tmp2 = aux2->prev; 56 | if (!aux2->prev) 57 | *list = aux2; 58 | flag = 1; 59 | if (!head_tmp2) 60 | break; 61 | aux_num1 = aux_num_fun(head_tmp2); 62 | aux_num2 = aux_num_fun(head_tmp2->next); 63 | } 64 | if (flag == 0) 65 | head_tmp1 = head_tmp1->next; 66 | } 67 | head_tmp1 = head_tmp1->next; 68 | } 69 | } 70 | /** 71 | * kind_sort - sorts a doubly linked list of integers 72 | * in ascending order using the Insertion sort ailgorithm 73 | * @list: pointer to the list head 74 | * Return: no return 75 | **/ 76 | void kind_sort(deck_node_t **list) 77 | { 78 | deck_node_t *head_tmp1, *head_tmp2, *aux1, *aux2; 79 | int flag; 80 | 81 | if (list) 82 | { 83 | head_tmp1 = *list; 84 | head_tmp2 = *list; 85 | while (list && head_tmp1->next) 86 | { 87 | if (head_tmp1->next) 88 | { 89 | flag = 0; 90 | head_tmp2 = head_tmp1; 91 | while (head_tmp2 && head_tmp2->card->kind > head_tmp2->next->card->kind) 92 | { 93 | aux1 = head_tmp2; 94 | aux2 = head_tmp2->next; 95 | aux1->next = aux2->next; 96 | if (aux2->next) 97 | aux2->next->prev = aux1; 98 | if (aux2) 99 | { 100 | aux2->prev = aux1->prev; 101 | aux2->next = aux1; 102 | } 103 | if (aux1) 104 | aux1->prev = aux2; 105 | if (aux2->prev) 106 | aux2->prev->next = aux2; 107 | head_tmp2 = aux2->prev; 108 | if (!aux2->prev) 109 | *list = aux2; 110 | flag = 1; 111 | } 112 | } 113 | if (flag == 0) 114 | head_tmp1 = head_tmp1->next; 115 | } 116 | } 117 | } 118 | /** 119 | * sort_deck - sorts a deck of cards 120 | * @deck: ponter to the deck 121 | * Return: no return 122 | * 123 | **/ 124 | void sort_deck(deck_node_t **deck) 125 | { 126 | if (deck) 127 | { 128 | kind_sort(deck); 129 | num_sort(deck); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sorting algorithms & Big O 2 | 3 | ## Description 4 | 5 | This repository contains programs written in C language that implement different sorting algorithms and analyze their time and space complexities. 6 | 7 | The implemented sorting algorithms are: 8 | 9 | - Bubble Sort 10 | - Insertion Sort 11 | - Selection Sort 12 | - Quick Sort 13 | - Shell Sort 14 | - Cocktail Sort 15 | - Counting Sort 16 | - Merge Sort 17 | - radix_sort 18 | - bitonic sort 19 | - quick sort hoare 20 | 21 | ## Files 22 | 23 | The repository contains the following files: 24 | 25 | | File | Description | 26 | |------|-------------| 27 | | `sort.h` | Header file with function prototypes | 28 | | `print_array.c` | Function that prints an array | 29 | | `swap.c` | Function that swaps the values of two integers | 30 | | `0-bubble_sort.c` | Function that implements the bubble sort algorithm | 31 | | `0-O` | Text file with the big O notation of the bubble sort algorithm | 32 | | `1-insertion_sort_list.c` | Function that implements the insertion sort algorithm | 33 | | `1-O` | Text file with the big O notation of the insertion sort algorithm | 34 | | `2-selection_sort.c` | Function that implements the selection sort algorithm | 35 | | `2-O` | Text file with the big O notation of the selection sort algorithm | 36 | | `3-quick_sort.c` | Function that implements the quick sort algorithm | 37 | | `3-O` | Text file with the big O notation of the quick sort algorithm | 38 | | `100-shell_sort.c` | Function that implements the shell sort algorithm | 39 | | `100-O` | Text file with the big O notation of the shell sort algorithm | 40 | | `101-cocktail_sort_list.c` | Function that implements the cocktail sort algorithm | 41 | | `101-O` | Text file with the big O notation of the cocktail sort algorithm | 42 | | `102-counting_sort.c` | Function that implements the counting sort algorithm | 43 | | `102-O` | Text file with the big O notation of the counting sort algorithm | 44 | | `103-merge_sort.c` | Function that implements the merge sort algorithm | 45 | | `103-O` | Text file with the big O notation of the merge sort algorithm | 46 | | `sort-main.c` | Main function to test the sorting algorithms | 47 | 48 | ## Requirements 49 | 50 | The programs were written in C language and compiled using the `gcc` compiler with the flags `-Wall`, `-Werror`, `-Wextra`, and `-pedantic`. 51 | 52 | The header file `sort.h` contains the following function prototypes: 53 | 54 | ```c 55 | #include 56 | /** 57 | * struct listint_s - Doubly linked list node 58 | * 59 | * @n: Integer stored in the node 60 | * @prev: Pointer to the previous element of the list 61 | * @next: Pointer to the next element of the list 62 | */ 63 | typedef struct listint_s 64 | { 65 | const int n; 66 | struct listint_s *prev; 67 | struct listint_s *next; 68 | } listint_t; 69 | 70 | void bubble_sort(int *array, size_t size); 71 | void print_array(const int *array, size_t size); 72 | void print_list(const listint_t *list); 73 | listint_t *swap_node(listint_t *node, listint_t **list); 74 | void insertion_sort_list(listint_t **list); 75 | void selection_sort(int *array, size_t size); 76 | void quick_sort(int *array, size_t size); 77 | void shell_sort(int *array, size_t size); 78 | void cocktail_sort_list(listint_t **list); 79 | void counting_sort(int *array, size_t size); 80 | void merge_sort(int *array, size_t size); 81 | void heap_sort(int *array, size_t size); 82 | void radix_sort(int *array, size_t size); 83 | void bitonic_sort(int *array, size_t size); 84 | void quick_sort_hoare(int *array, size_t size); 85 | ```` 86 | # Usage 87 | 88 | To test the sorting algorithms, compile the files using gcc and execute the resulting binary: 89 | 90 | ``` 91 | $ gcc -Wall -Werror -Wextra -pedantic *.c -o sort 92 | $ ./sort 93 | ``` 94 | You can also include the sort.h header file in your own programs and use the sorting functions as needed. 95 | 96 | # Author 97 | 98 | This project was implemented by: 99 | 100 | * [Solomon Kassa](https://github.com/Solomonkassa) 101 | * [Adissu Mulat](https://github.com/Adika1630) 102 | 103 | --------------------------------------------------------------------------------