├── 0-O ├── 1-O ├── 101-O ├── 102-O ├── 105-O ├── 2-O ├── 107-O ├── 3-O ├── 103-O ├── 104-O ├── 106-O ├── README.md ├── .3-quick_sort.c.swp ├── .0-bubble_sort.c.swp ├── .1-insertion_sort_list.c.swo ├── .1-insertion_sort_list.c.swp ├── print_list.c ├── print_array.c ├── 2-selection_sort.c ├── 0-bubble_sort.c ├── 100-shell_sort.c ├── deck.h ├── 102-counting_sort.c ├── 1-insertion_sort_list.c ├── sort.h ├── 3-quick_sort.c ├── 104-heap_sort.c ├── 105-radix_sort.c ├── 103-merge_sort.c ├── 107-quick_sort_hoare.c ├── 106-bitonic_sort.c ├── 101-cocktail_sort_list.c └── 1000-sort_deck.c /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sorting_algorithms 2 | # sorting_algorithms 3 | -------------------------------------------------------------------------------- /.3-quick_sort.c.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/victor0089/sorting_algorithms/HEAD/.3-quick_sort.c.swp -------------------------------------------------------------------------------- /.0-bubble_sort.c.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/victor0089/sorting_algorithms/HEAD/.0-bubble_sort.c.swp -------------------------------------------------------------------------------- /.1-insertion_sort_list.c.swo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/victor0089/sorting_algorithms/HEAD/.1-insertion_sort_list.c.swo -------------------------------------------------------------------------------- /.1-insertion_sort_list.c.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/victor0089/sorting_algorithms/HEAD/.1-insertion_sort_list.c.swp -------------------------------------------------------------------------------- /print_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sort.h" 3 | 4 | /** 5 | * print_list - Prints a list of integers 6 | * @list: The list to be printed 7 | */ 8 | void print_list(const listint_t *list) 9 | { 10 | int i; 11 | 12 | i = 0; 13 | while (list) 14 | { 15 | if (i > 0) 16 | printf(", "); 17 | printf("%d", list->n); 18 | ++i; 19 | list = list->next; 20 | } 21 | printf("\n"); 22 | } 23 | -------------------------------------------------------------------------------- /print_array.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** 5 | * print_array - Prints an array of integers 6 | * @array: The array to be printed 7 | * @size: Number of elements in @array 8 | */ 9 | void print_array(const int *array, size_t size) 10 | { 11 | size_t i; 12 | 13 | i = 0; 14 | while (array && i < size) 15 | { 16 | if (i > 0) 17 | printf(", "); 18 | printf("%d", array[i]); 19 | ++i; 20 | } 21 | printf("\n"); 22 | } 23 | -------------------------------------------------------------------------------- /2-selection_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | /** 3 | * selection_sort - sorts an array of integers (By Jacko) 4 | * @array: array of integers to be sorted 5 | * @size: amount of elements in array 6 | */ 7 | 8 | void selection_sort(int *array, size_t size) 9 | { 10 | size_t i, index; 11 | int tmp, swap, flag = 0; 12 | 13 | if (array == NULL) 14 | return; 15 | for (i = 0; i < size; i++) 16 | { 17 | tmp = i; 18 | flag = 0; 19 | for (index = i + 1; index < size; index++) 20 | { 21 | if (array[tmp] > array[index]) 22 | { 23 | tmp = index; 24 | flag += 1; 25 | } 26 | } 27 | swap = array[i]; 28 | array[i] = array[tmp]; 29 | array[tmp] = swap; 30 | if (flag != 0) 31 | print_array(array, size); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /0-bubble_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | /** 4 | * swap_ints - Swaptwo integersanarray. 5 | * @a: The first integer swap. 6 | * @b: The second integer swap. 7 | */ 8 | void swap_ints(int *a, int *b) 9 | { 10 | int tmp; 11 | 12 | tmp = *a; 13 | *a = *b; 14 | *b = tmp; 15 | } 16 | 17 | /** 18 | * bubble_sort - Sort anrray integers in ascending . 19 | * @array: An array of integers to sort. 20 | * @size: The size array. 21 | * Description: Prints array each swap. 22 | */ 23 | void bubble_sort(int *array, size_t size) 24 | { 25 | size_t i, len = size; 26 | bool bubbly = false; 27 | 28 | if (array == NULL || size < 2) 29 | return; 30 | 31 | while (bubbly == false) 32 | { 33 | bubbly = true; 34 | for (i = 0; i < len - 1; i++) 35 | { 36 | if (array[i] > array[i + 1]) 37 | { 38 | swap_ints(array + i, array + i + 1); 39 | print_array(array, size); 40 | bubbly = false; 41 | } 42 | } 43 | len--; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /100-shell_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | /** 3 | * swap_ints - Swap two integersinanarray. 4 | * @a: The firstntegertoswap. 5 | * @b: The second integeroswap. 6 | */ 7 | void swap_ints(int *a, int *b) 8 | { 9 | int tmp; 10 | tmp = *a; 11 | *a = *b; 12 | *b = tmp; 13 | } 14 | 15 | /** 16 | * shell_sort - Sortanarrayofintegersi ascending 17 | * order using the shell sort algorithm. 18 | * @array: An arrayofintegers. 19 | * @size: The sizeofthearray. 20 | * 21 | * Description: Uses theKnuthntervalsequence. 22 | */ 23 | void shell_sort(int *array, size_t size) 24 | { 25 | size_t gp, i, j; 26 | if (array == NULL || size < 2) 27 | return; 28 | for (gp = 1; gp < (size / 3);) 29 | gp = gp * 3 + 1; 30 | for (; gp >= 1; gp /= 3) 31 | { 32 | for (i = gp; i < size; i++) 33 | { 34 | j = i; 35 | while (j >= gp && array[j - gp] > array[j]) 36 | { 37 | swap_ints(array + j, array + (j - gp)); 38 | j -= gp; 39 | } 40 | } 41 | print_array(array, size); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /deck.h: -------------------------------------------------------------------------------- 1 | #ifndef DECK_H 2 | #define DECK_H 3 | #include 4 | 5 | /** 6 | * enum kind_e - Enumerationcard suits. 7 | * @SPADE: Spadessuit. 8 | * @HEART: Heartssuit. 9 | * @CLUB: Clubssuit. 10 | * @DIAMOND: Diamondssuit. 11 | */ 12 | typedef enum kind_e 13 | { 14 | SPADE = 0, 15 | HEART, 16 | CLUB, 17 | DIAMOND 18 | } kind_t; 19 | 20 | /** 21 | * struct card_s - Playing card 22 | * @value: Value ofthecard 23 | * From "Ace" to "King" 24 | * @kind: Kind ofthecard 25 | */ 26 | typedef struct card_s 27 | { 28 | const char *value; 29 | const kind_t kind; 30 | } card_t; 31 | 32 | /** 33 | * struct deck_node_s - Deck of card 34 | * 35 | * @card: Pointer tothe cardof the node 36 | * @prev: Pointer tothe previousnode of the list 37 | * @next: Pointer tothe next nodeof the list 38 | */ 39 | typedef struct deck_node_s 40 | { 41 | const card_t *card; 42 | struct deck_node_s *prev; 43 | struct deck_node_s *next; 44 | } deck_node_t; 45 | 46 | void sort_deck(deck_node_t **deck); 47 | 48 | #endif /* DECK_H */ 49 | -------------------------------------------------------------------------------- /102-counting_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | /** 3 | * counting_sort - sorts an array of integers in ascending order 4 | * using the Counting sort algorithm 5 | * @array: the array to be sorted 6 | * @size: the size of the array 7 | * Return: Nothing 8 | */ 9 | void counting_sort(int *array, size_t size) 10 | { 11 | int max, i, j, k; 12 | int *count, *output; 13 | if (array == NULL || size < 2) 14 | return; 15 | max = array[0]; 16 | for (i = 1; i < (int)size; i++) 17 | { 18 | if (array[i] > max) 19 | max = array[i]; 20 | } 21 | count = malloc(sizeof(int) * (max + 1)); 22 | output = malloc(sizeof(int) * size); 23 | if (count == NULL || output == NULL) 24 | return; 25 | for (i = 0; i <= max; i++) 26 | count[i] = 0; 27 | for (j = 0; j < (int)size; j++) 28 | count[array[j]]++; 29 | for (i = 1; i <= max; i++) 30 | count[i] += count[i - 1]; 31 | print_array(count, max + 1); 32 | for (j = size - 1; j >= 0; j--) 33 | { 34 | output[count[array[j]] - 1] = array[j]; 35 | count[array[j]]--; 36 | } 37 | for (k = 0; k < (int)size; k++) 38 | array[k] = output[k]; 39 | free(count); 40 | free(output); 41 | } 42 | -------------------------------------------------------------------------------- /1-insertion_sort_list.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | /** 3 | * insertion_sort_list - function that sorts a doubly linked list 4 | * @list: Dobule linked list to sort 5 | */ 6 | void insertion_sort_list(listint_t **list) 7 | { 8 | listint_t *node; 9 | 10 | if (list == NULL || (*list)->next == NULL) 11 | return; 12 | node = (*list)->next; 13 | while (node) 14 | { 15 | while ((node->prev) && (node->prev->n > node->n)) 16 | { 17 | node = swap_node(node, list); 18 | print_list(*list); 19 | } 20 | node = node->next; 21 | } 22 | } 23 | /** 24 | *swap_node - swap a node for his previous one 25 | *@node: node 26 | *@list: node list 27 | *Return: return a pointer to a node which was enter it 28 | */ 29 | listint_t *swap_node(listint_t *node, listint_t **list) 30 | { 31 | listint_t *back = node->prev, *current = node; 32 | /*NULL, 19, 48, 9, 71, 13, NULL*/ 33 | 34 | back->next = current->next; 35 | if (current->next) 36 | current->next->prev = back; 37 | current->next = back; 38 | current->prev = back->prev; 39 | back->prev = current; 40 | if (current->prev) 41 | current->prev->next = current; 42 | else 43 | *list = current; 44 | return (current); 45 | } 46 | -------------------------------------------------------------------------------- /sort.h: -------------------------------------------------------------------------------- 1 | #ifndef SORT_H 2 | #define SORT_H 3 | 4 | #include 5 | #include 6 | /* Comparison macros bitonic sort */ 7 | #define UP 0 8 | #define DOWN 1 9 | 10 | /** 11 | * enum bool - Enumeration Boolean values. 12 | * @false: Equals 0. 13 | * @true: Equals 1. 14 | */ 15 | typedef enum bool 16 | { 17 | false = 0, 18 | true 19 | } bool; 20 | 21 | /** 22 | * struct listint_s - Doubly linked list node 23 | * 24 | * @n: Integer stored in the node 25 | * @prev: Pointer to the previous element of the list 26 | * @next: Pointer to the next element of the list 27 | */ 28 | typedef struct listint_s 29 | { 30 | const int n; 31 | struct listint_s *prev; 32 | struct listint_s *next; 33 | } listint_t; 34 | 35 | void bubble_sort(int *array, size_t size); 36 | void print_array(const int *array, size_t size); 37 | void print_list(const listint_t *list); 38 | listint_t *swap_node(listint_t *node, listint_t **list); 39 | void insertion_sort_list(listint_t **list); 40 | void selection_sort(int *array, size_t size); 41 | void quick_sort(int *array, size_t size); 42 | void shell_sort(int *array, size_t size); 43 | void cocktail_sort_list(listint_t **list); 44 | void counting_sort(int *array, size_t size); 45 | void merge_sort(int *array, size_t size); 46 | void heap_sort(int *array, size_t size); 47 | void radix_sort(int *array, size_t size); 48 | void bitonic_sort(int *array, size_t size); 49 | void quick_sort_hoare(int *array, size_t size); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /3-quick_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | /** 3 | *swap - the positions of 2 elements into an array 4 | *@array: array 5 | *@item1: array element 6 | *@item2: array element 7 | */ 8 | void swap(int *array, ssize_t item1, ssize_t item2) 9 | { 10 | int tmp; 11 | 12 | tmp = array[item1]; 13 | array[item1] = array[item2]; 14 | array[item2] = tmp; 15 | } 16 | /** 17 | *lomuto_partition - sorting scheme implementation 18 | *@array: array 19 | *@first: 1st array element 20 | *@last: last array element 21 | *@size: size array 22 | *Return: return the position of the last element sorted 23 | */ 24 | int lomuto_partition(int *array, ssize_t first, ssize_t last, size_t size) 25 | { 26 | int pivot = array[last]; 27 | ssize_t current = first, finder; 28 | 29 | for (finder = first; finder < last; finder++) 30 | { 31 | if (array[finder] < pivot) 32 | { 33 | if (array[current] != array[finder]) 34 | { 35 | swap(array, current, finder); 36 | print_array(array, size); 37 | } 38 | current++; 39 | } 40 | } 41 | if (array[current] != array[last]) 42 | { 43 | swap(array, current, last); 44 | print_array(array, size); 45 | } 46 | return (current); 47 | } 48 | /** 49 | *qs - quicksort algo implementation 50 | *@array: array 51 | *@first: first array element 52 | *@last: last array element 53 | *@size: array size 54 | */ 55 | void qs(int *array, ssize_t first, ssize_t last, int size) 56 | { 57 | ssize_t position = 0; 58 | 59 | 60 | if (first < last) 61 | { 62 | position = lomuto_partition(array, first, last, size); 63 | 64 | qs(array, first, position - 1, size); 65 | qs(array, position + 1, last, size); 66 | } 67 | } 68 | /** 69 | *quick_sort - prepare the terrain to quicksort algorithm 70 | *@array: array 71 | *@size: array size 72 | */ 73 | void quick_sort(int *array, size_t size) 74 | { 75 | if (!array || size < 2) 76 | return; 77 | qs(array, 0, size - 1, size); 78 | } 79 | -------------------------------------------------------------------------------- /104-heap_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | void swap_ints(int *a, int *b); 4 | void max_heapify(int *array, size_t size, size_t base, size_t root); 5 | void heap_sort(int *array, size_t size); 6 | 7 | /** 8 | * swap_ints - Swap two integers in an array. 9 | * @a: The first inger to swap. 10 | * @b: The second integer to swap. 11 | */ 12 | void swap_ints(int *a, int *b) 13 | { 14 | int tmp; 15 | 16 | tmp = *a; 17 | *a = *b; 18 | *b = tmp; 19 | } 20 | 21 | /** 22 | * max_heapify - Turn a binary tree into a complete binary heap. 23 | * @array: An array of integers representing a binary tree. 24 | * @size: The size of the array/tree. 25 | * @base: The index of the base row of the tree. 26 | * @root: The root node of the binary tree. 27 | */ 28 | void max_heapify(int *array, size_t size, size_t base, size_t root) 29 | { 30 | size_t left, right, large; 31 | 32 | left = 2 * root + 1; 33 | right = 2 * root + 2; 34 | large = root; 35 | 36 | if (left < base && array[left] > array[large]) 37 | large = left; 38 | if (right < base && array[right] > array[large]) 39 | large = right; 40 | 41 | if (large != root) 42 | { 43 | swap_ints(array + root, array + large); 44 | print_array(array, size); 45 | max_heapify(array, size, base, large); 46 | } 47 | } 48 | 49 | /** 50 | * heap_sort - Sort an array of integers in ascending 51 | * order using the heap sort algorithm. 52 | * @array: An array of integers. 53 | * @size: The size of the array. 54 | * 55 | * Description: Implements the sift-down heap sort 56 | * algorithm. Prints the array after each swap. 57 | */ 58 | void heap_sort(int *array, size_t size) 59 | { 60 | int i; 61 | 62 | if (array == NULL || size < 2) 63 | return; 64 | 65 | for (i = (size / 2) - 1; i >= 0; i--) 66 | max_heapify(array, size, size, i); 67 | 68 | for (i = size - 1; i > 0; i--) 69 | { 70 | swap_ints(array, array + i); 71 | print_array(array, size); 72 | max_heapify(array, size, i, 0); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /105-radix_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | int get_max(int *array, int size); 4 | void radix_counting_sort(int *array, size_t size, int sig, int *buff); 5 | void radix_sort(int *array, size_t size); 6 | 7 | /** 8 | * get_max - Get the maximu value in an array of integers. 9 | * @array: An array of integers. 10 | * @size: The size of the array. 11 | * 12 | * Return: The maximum integer in the array. 13 | */ 14 | int get_max(int *array, int size) 15 | { 16 | int max, i; 17 | 18 | for (max = array[0], i = 1; i < size; i++) 19 | { 20 | if (array[i] > max) 21 | max = array[i]; 22 | } 23 | 24 | return (max); 25 | } 26 | 27 | /** 28 | * radix_counting_sort - Sort the significant digits of an array of integers 29 | * in ascending order using the counting sort algorithm. 30 | * @array: An array of integers. 31 | * @size: The size of the array. 32 | * @sig: The significant digit to sort on. 33 | * @buff: A buffer to store the sorted array. 34 | */ 35 | void radix_counting_sort(int *array, size_t size, int sig, int *buff) 36 | { 37 | int count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 38 | size_t i; 39 | 40 | for (i = 0; i < size; i++) 41 | count[(array[i] / sig) % 10] += 1; 42 | 43 | for (i = 0; i < 10; i++) 44 | count[i] += count[i - 1]; 45 | 46 | for (i = size - 1; (int)i >= 0; i--) 47 | { 48 | buff[count[(array[i] / sig) % 10] - 1] = array[i]; 49 | count[(array[i] / sig) % 10] -= 1; 50 | } 51 | 52 | for (i = 0; i < size; i++) 53 | array[i] = buff[i]; 54 | } 55 | 56 | /** 57 | * radix_sort - Sort an array of integers in ascending 58 | * order using the radix sort algorithm. 59 | * @array: An array of integers. 60 | * @size: The size of the array. 61 | * 62 | * Description: Implements the LSD radix sort algorithm. Prints 63 | * the array after each significant digit increase. 64 | */ 65 | void radix_sort(int *array, size_t size) 66 | { 67 | int max, sig, *buff; 68 | 69 | if (array == NULL || size < 2) 70 | return; 71 | 72 | buff = malloc(sizeof(int) * size); 73 | if (buff == NULL) 74 | return; 75 | 76 | max = get_max(array, size); 77 | for (sig = 1; max / sig > 0; sig *= 10) 78 | { 79 | radix_counting_sort(array, size, sig, buff); 80 | print_array(array, size); 81 | } 82 | 83 | free(buff); 84 | } 85 | -------------------------------------------------------------------------------- /103-merge_sort.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | #include 3 | 4 | void merge_subarr(int *subarr, int *buff, size_t front, size_t mid, 5 | size_t back); 6 | void merge_sort_recursive(int *subarr, int *buff, size_t front, size_t back); 7 | void merge_sort(int *array, size_t size); 8 | 9 | /** 10 | * merge_subarr - Sort a subarray of integers. 11 | * @subarr: A subarray of an array of integers to sort. 12 | * @buff: A buffer to store the sorted subarray. 13 | * @front: The front index of the array. 14 | * @mid: The middle index of the array. 15 | * @back: The back index of the array. 16 | */ 17 | void merge_subarr(int *subarr, int *buff, size_t front, size_t mid, 18 | size_t back) 19 | { 20 | size_t i, j, k = 0; 21 | 22 | printf("Merging...\n[left]: "); 23 | print_array(subarr + front, mid - front); 24 | 25 | printf("[right]: "); 26 | print_array(subarr + mid, back - mid); 27 | 28 | for (i = front, j = mid; i < mid && j < back; k++) 29 | buff[k] = (subarr[i] < subarr[j]) ? subarr[i++] : subarr[j++]; 30 | for (; i < mid; i++) 31 | buff[k++] = subarr[i]; 32 | for (; j < back; j++) 33 | buff[k++] = subarr[j]; 34 | for (i = front, k = 0; i < back; i++) 35 | subarr[i] = buff[k++]; 36 | 37 | printf("[Done]: "); 38 | print_array(subarr + front, back - front); 39 | } 40 | 41 | /** 42 | * merge_sort_recursive - Implement the merge sort algorithm through recursion. 43 | * @subarr: A subarray of an array of integers to sort. 44 | * @buff: A buffer to store the sorted result. 45 | * @front: The front index of the subarray. 46 | * @back: The back index of the subarray. 47 | */ 48 | void merge_sort_recursive(int *subarr, int *buff, size_t front, size_t back) 49 | { 50 | size_t mid; 51 | 52 | if (back - front > 1) 53 | { 54 | mid = front + (back - front) / 2; 55 | merge_sort_recursive(subarr, buff, front, mid); 56 | merge_sort_recursive(subarr, buff, mid, back); 57 | merge_subarr(subarr, buff, front, mid, back); 58 | } 59 | } 60 | 61 | /** 62 | * merge_sort - Sort an array of integers in ascending 63 | * order using the merge sort algorithm. 64 | * @array: An array of integers. 65 | * @size: The size of the array. 66 | * Description: Implements the top-down merge sort algorithm. 67 | */ 68 | void merge_sort(int *array, size_t size) 69 | { 70 | int *buff; 71 | 72 | if (array == NULL || size < 2) 73 | return; 74 | 75 | buff = malloc(sizeof(int) * size); 76 | if (buff == NULL) 77 | return; 78 | 79 | merge_sort_recursive(array, buff, 0, size); 80 | 81 | free(buff); 82 | } 83 | -------------------------------------------------------------------------------- /107-quick_sort_hoare.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | void swap_ints(int *a, int *b); 4 | int hoare_partition(int *array, size_t size, int left, int right); 5 | void hoare_sort(int *array, size_t size, int left, int right); 6 | void quick_sort_hoare(int *array, size_t size); 7 | 8 | /** 9 | * swap_ints - Swap two integers in an array. 10 | * @a: The first integer to swap. 11 | * @b: The second integer to swap. 12 | */ 13 | void swap_ints(int *a, int *b) 14 | { 15 | int tmp; 16 | 17 | tmp = *a; 18 | *a = *b; 19 | *b = tmp; 20 | } 21 | 22 | /** 23 | * hoare_partition - Order a subset of an array of integers 24 | * according to the hoare partition scheme. 25 | * @array: The array of integers. 26 | * @size: The size of the array. 27 | * @left: The starting index of the subset to order. 28 | * @right: The ending index of the subset to order. 29 | * Return: The final partition index. 30 | * Description: Uses the last element of the partition as the pivot. 31 | * Prints the array after each swap of two elements. 32 | */ 33 | int hoare_partition(int *array, size_t size, int left, int right) 34 | { 35 | int pivot, above, below; 36 | 37 | pivot = array[right]; 38 | for (above = left - 1, below = right + 1; above < below;) 39 | { 40 | do { 41 | above++; 42 | } while (array[above] < pivot); 43 | do { 44 | below--; 45 | } while (array[below] > pivot); 46 | 47 | if (above < below) 48 | { 49 | swap_ints(array + above, array + below); 50 | print_array(array, size); 51 | } 52 | } 53 | 54 | return (above); 55 | } 56 | 57 | /** 58 | * hoare_sort - Implement the quicksort algorithm through recursion. 59 | * @array: An array of integers to sort. 60 | * @size: The size of the array. 61 | * @left: The starting index of the array partition to order. 62 | * @right: The ending index of the array partition to order. 63 | * Description: Uses the Hoare partition scheme. 64 | */ 65 | void hoare_sort(int *array, size_t size, int left, int right) 66 | { 67 | int part; 68 | 69 | if (right - left > 0) 70 | { 71 | part = hoare_partition(array, size, left, right); 72 | hoare_sort(array, size, left, part - 1); 73 | hoare_sort(array, size, part, right); 74 | } 75 | } 76 | 77 | /** 78 | * quick_sort_hoare - Sort an array of integers in ascending 79 | * order using the quicksort algorithm. 80 | * @array: An array of integers. 81 | * @size: The size of the array. 82 | * 83 | * Description: Uses the Hoare partition scheme. Prints 84 | * the array after each swap of two elements. 85 | */ 86 | void quick_sort_hoare(int *array, size_t size) 87 | { 88 | if (array == NULL || size < 2) 89 | return; 90 | 91 | hoare_sort(array, size, 0, size - 1); 92 | } 93 | -------------------------------------------------------------------------------- /106-bitonic_sort.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: 106-bitonic_sort.c 3 | * Auth: victor israel 4 | */ 5 | 6 | #include "sort.h" 7 | #include 8 | 9 | void swap_ints(int *a, int *b); 10 | void bitonic_merge(int *array, size_t size, size_t start, size_t seq, 11 | char flow); 12 | void bitonic_seq(int *array, size_t size, size_t start, size_t seq, char flow); 13 | void bitonic_sort(int *array, size_t size); 14 | 15 | /** 16 | * swap_ints - Swap two integers in an array. 17 | * @a: The first integer to swap. 18 | * @b: The second integer to swap. 19 | */ 20 | void swap_ints(int *a, int *b) 21 | { 22 | int tmp; 23 | 24 | tmp = *a; 25 | *a = *b; 26 | *b = tmp; 27 | } 28 | 29 | /** 30 | * bitonic_merge - Sort a bitonic sequence inside an array of integers. 31 | * @array: An array of integers. 32 | * @size: The size of the array. 33 | * @start: The starting index of the sequence in array to sort. 34 | * @seq: The size of the sequence to sort. 35 | * @flow: The direction to sort in. 36 | */ 37 | void bitonic_merge(int *array, size_t size, size_t start, size_t seq, 38 | char flow) 39 | { 40 | size_t i, jump = seq / 2; 41 | 42 | if (seq > 1) 43 | { 44 | for (i = start; i < start + jump; i++) 45 | { 46 | if ((flow == UP && array[i] > array[i + jump]) || 47 | (flow == DOWN && array[i] < array[i + jump])) 48 | swap_ints(array + i, array + i + jump); 49 | } 50 | bitonic_merge(array, size, start, jump, flow); 51 | bitonic_merge(array, size, start + jump, jump, flow); 52 | } 53 | } 54 | 55 | /** 56 | * bitonic_seq - Convert an array of integers into a bitonic sequence. 57 | * @array: An array of integers. 58 | * @size: The size of the array. 59 | * @start: The starting index of a block of the building bitonic sequence. 60 | * @seq: The size of a block of the building bitonic sequence. 61 | * @flow: The direction to sort the bitonic sequence block in. 62 | */ 63 | void bitonic_seq(int *array, size_t size, size_t start, size_t seq, char flow) 64 | { 65 | size_t cut = seq / 2; 66 | char *str = (flow == UP) ? "UP" : "DOWN"; 67 | 68 | if (seq > 1) 69 | { 70 | printf("Merging [%lu/%lu] (%s):\n", seq, size, str); 71 | print_array(array + start, seq); 72 | 73 | bitonic_seq(array, size, start, cut, UP); 74 | bitonic_seq(array, size, start + cut, cut, DOWN); 75 | bitonic_merge(array, size, start, seq, flow); 76 | 77 | printf("Result [%lu/%lu] (%s):\n", seq, size, str); 78 | print_array(array + start, seq); 79 | } 80 | } 81 | 82 | /** 83 | * bitonic_sort - Sort an array of integers in ascending 84 | * order using the bitonic sort algorithm. 85 | * @array: An array of integers. 86 | * @size: The size of the array. 87 | * Description: Prints the array after each swap. Only works for 88 | * size = 2^k where k >= 0 (ie. size equal to powers of 2). 89 | */ 90 | void bitonic_sort(int *array, size_t size) 91 | { 92 | if (array == NULL || size < 2) 93 | return; 94 | 95 | bitonic_seq(array, size, 0, size, UP); 96 | } 97 | -------------------------------------------------------------------------------- /101-cocktail_sort_list.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | void swap_node_ahead(listint_t **list, listint_t **tail, listint_t **shaker); 4 | void swap_node_behind(listint_t **list, listint_t **tail, listint_t **shaker); 5 | void cocktail_sort_list(listint_t **list); 6 | 7 | /** 8 | * swap_node_ahead - Swap a node in a listint_t doubly-linked list 9 | * list of integers with the node ahead of it. 10 | * @list: A pointer to the head of a doubly-linked list of integers. 11 | * @tail: A pointer to the tail of the doubly-linked list. 12 | * @shaker: A pointer to the current swapping node of the cocktail shaker algo. 13 | */ 14 | void swap_node_ahead(listint_t **list, listint_t **tail, listint_t **shaker) 15 | { 16 | listint_t *tmp = (*shaker)->next; 17 | 18 | if ((*shaker)->prev != NULL) 19 | (*shaker)->prev->next = tmp; 20 | else 21 | *list = tmp; 22 | tmp->prev = (*shaker)->prev; 23 | (*shaker)->next = tmp->next; 24 | if (tmp->next != NULL) 25 | tmp->next->prev = *shaker; 26 | else 27 | *tail = *shaker; 28 | (*shaker)->prev = tmp; 29 | tmp->next = *shaker; 30 | *shaker = tmp; 31 | } 32 | 33 | /** 34 | * swap_node_behind - Swap a node in a listint_t doubly-linked 35 | * list of integers with the node behind it. 36 | * @list: A pointer to the head of a doubly-linked list of integers. 37 | * @tail: A pointer to the tail of the doubly-linked list. 38 | * @shaker: A pointer to the current swapping node of the cocktail shaker algo. 39 | */ 40 | void swap_node_behind(listint_t **list, listint_t **tail, listint_t **shaker) 41 | { 42 | listint_t *tmp = (*shaker)->prev; 43 | 44 | if ((*shaker)->next != NULL) 45 | (*shaker)->next->prev = tmp; 46 | else 47 | *tail = tmp; 48 | tmp->next = (*shaker)->next; 49 | (*shaker)->prev = tmp->prev; 50 | if (tmp->prev != NULL) 51 | tmp->prev->next = *shaker; 52 | else 53 | *list = *shaker; 54 | (*shaker)->next = tmp; 55 | tmp->prev = *shaker; 56 | *shaker = tmp; 57 | } 58 | 59 | /** 60 | * cocktail_sort_list - Sort a listint_t doubly-lnked list of integers in 61 | * ascending order using the cocktail shaker algorithm. 62 | * @list: A pointer to the head of a listint_t doubly-linked list. 63 | */ 64 | void cocktail_sort_list(listint_t **list) 65 | { 66 | listint_t *tail, *shaker; 67 | bool shaken_not_stirred = false; 68 | 69 | if (list == NULL || *list == NULL || (*list)->next == NULL) 70 | return; 71 | 72 | for (tail = *list; tail->next != NULL;) 73 | tail = tail->next; 74 | 75 | while (shaken_not_stirred == false) 76 | { 77 | shaken_not_stirred = true; 78 | for (shaker = *list; shaker != tail; shaker = shaker->next) 79 | { 80 | if (shaker->n > shaker->next->n) 81 | { 82 | swap_node_ahead(list, &tail, &shaker); 83 | print_list((const listint_t *)*list); 84 | shaken_not_stirred = false; 85 | } 86 | } 87 | for (shaker = shaker->prev; shaker != *list; 88 | shaker = shaker->prev) 89 | { 90 | if (shaker->n < shaker->prev->n) 91 | { 92 | swap_node_behind(list, &tail, &shaker); 93 | print_list((const listint_t *)*list); 94 | shaken_not_stirred = false; 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /1000-sort_deck.c: -------------------------------------------------------------------------------- 1 | #include "deck.h" 2 | 3 | int _strcmp(const char *s1, const char *s2); 4 | char get_value(deck_node_t *card); 5 | void insertion_sort_deck_kind(deck_node_t **deck); 6 | void insertion_sort_deck_value(deck_node_t **deck); 7 | void sort_deck(deck_node_t **deck); 8 | 9 | /** 10 | * _strcmp - Compares twostrings. 11 | * @s1: The first stringto be compared. 12 | * @s2: The secondstringto be compared. 13 | * 14 | * Return: Positive byte difference if s1 > s2 15 | * 0 if s1 == s2 16 | * Negative byte difference if s1 < s2 17 | */ 18 | int _strcmp(const char *s1, const char *s2) 19 | { 20 | while (*s1 && *s2 && *s1 == *s2) 21 | { 22 | s1++; 23 | s2++; 24 | } 25 | 26 | if (*s1 != *s2) 27 | return (*s1 - *s2); 28 | return (0); 29 | } 30 | 31 | /** 32 | * get_value - Get the numericalvalue of a card. 33 | * @card: A pointerto a deck_node_tcard. 34 | * Return: The numerical value of the card. 35 | */ 36 | char get_value(deck_node_t *card) 37 | { 38 | if (_strcmp(card->card->value, "Ace") == 0) 39 | return (0); 40 | if (_strcmp(card->card->value, "1") == 0) 41 | return (1); 42 | if (_strcmp(card->card->value, "2") == 0) 43 | return (2); 44 | if (_strcmp(card->card->value, "3") == 0) 45 | return (3); 46 | if (_strcmp(card->card->value, "4") == 0) 47 | return (4); 48 | if (_strcmp(card->card->value, "5") == 0) 49 | return (5); 50 | if (_strcmp(card->card->value, "6") == 0) 51 | return (6); 52 | if (_strcmp(card->card->value, "7") == 0) 53 | return (7); 54 | if (_strcmp(card->card->value, "8") == 0) 55 | return (8); 56 | if (_strcmp(card->card->value, "9") == 0) 57 | return (9); 58 | if (_strcmp(card->card->value, "10") == 0) 59 | return (10); 60 | if (_strcmp(card->card->value, "Jack") == 0) 61 | return (11); 62 | if (_strcmp(card->card->value, "Queen") == 0) 63 | return (12); 64 | return (13); 65 | } 66 | 67 | /** 68 | * insertion_sort_deck_kind - Sort a deck of cards from spades to diamonds. 69 | * @deck: A pointer to the head of a deck_node_t doubly-linked list. 70 | */ 71 | void insertion_sort_deck_kind(deck_node_t **deck) 72 | { 73 | deck_node_t *iter, *insert, *tmp; 74 | 75 | for (iter = (*deck)->next; iter != NULL; iter = tmp) 76 | { 77 | tmp = iter->next; 78 | insert = iter->prev; 79 | while (insert != NULL && insert->card->kind > iter->card->kind) 80 | { 81 | insert->next = iter->next; 82 | if (iter->next != NULL) 83 | iter->next->prev = insert; 84 | iter->prev = insert->prev; 85 | iter->next = insert; 86 | if (insert->prev != NULL) 87 | insert->prev->next = iter; 88 | else 89 | *deck = iter; 90 | insert->prev = iter; 91 | insert = iter->prev; 92 | } 93 | } 94 | } 95 | 96 | /** 97 | * insertion_sort_deck_value - Sort a deck of cards sorted from 98 | * spades to diamonds from ace to king. 99 | * @deck: A pointer to the head of a deck_node_t doubly-linked list. 100 | */ 101 | void insertion_sort_deck_value(deck_node_t **deck) 102 | { 103 | deck_node_t *iter, *insert, *tmp; 104 | 105 | for (iter = (*deck)->next; iter != NULL; iter = tmp) 106 | { 107 | tmp = iter->next; 108 | insert = iter->prev; 109 | while (insert != NULL && 110 | insert->card->kind == iter->card->kind && 111 | get_value(insert) > get_value(iter)) 112 | { 113 | insert->next = iter->next; 114 | if (iter->next != NULL) 115 | iter->next->prev = insert; 116 | iter->prev = insert->prev; 117 | iter->next = insert; 118 | if (insert->prev != NULL) 119 | insert->prev->next = iter; 120 | else 121 | *deck = iter; 122 | insert->prev = iter; 123 | insert = iter->prev; 124 | } 125 | } 126 | } 127 | 128 | /** 129 | * sort_deck - Sort a deck of cards from aceto kingand 130 | * from spades to diamonds. 131 | * @deck: A pointerto thehead ofa deck_node_tdoubly-linked list. 132 | */ 133 | void sort_deck(deck_node_t **deck) 134 | { 135 | if (deck == NULL || *deck == NULL || (*deck)->next == NULL) 136 | return; 137 | 138 | insertion_sort_deck_kind(deck); 139 | insertion_sort_deck_value(deck); 140 | } 141 | --------------------------------------------------------------------------------