Skip to content

Commit c611b2b

Browse files
committed
sorting algorithms
1 parent 5034c37 commit c611b2b

12 files changed

+820
-0
lines changed

100-shell_sort.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "sort.h"
2+
3+
/**
4+
* swap_nbrs - Swap two numbers in an array.
5+
* @x: first number to swap.
6+
* @y: second number to swap.
7+
*/
8+
void swap_nbrs(int *x, int *y)
9+
{
10+
int temp;
11+
12+
temp = *x;
13+
*x = *y;
14+
*y = temp;
15+
}
16+
17+
/**
18+
* shell_sort - Sort an array of numbers in ascending order
19+
* @array: An array of numbers.
20+
* @size: size of array.
21+
*
22+
* Description: Uses Knuth interval sequence.
23+
*/
24+
void shell_sort(int *array, size_t size)
25+
{
26+
size_t gapp, x, y;
27+
28+
if (array == NULL || size < 2)
29+
return;
30+
31+
for (gapp = 1; gapp < (size / 3);)
32+
gapp = gapp * 3 + 1;
33+
34+
for (; gapp >= 1; gapp /= 3)
35+
{
36+
for (x = gapp; x < size; x++)
37+
{
38+
y = x;
39+
while (y >= gapp && array[y - gapp] > array[y])
40+
{
41+
swap_nbrs(array + y, array + (y - gapp));
42+
y -= gapp;
43+
}
44+
}
45+
print_array(array, size);
46+
}
47+
}

101-cocktail_sort_list.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#include "sort.h"
2+
3+
void swap_ahead(listint_t **list, listint_t **taill, listint_t **shakr);
4+
void swap_behind(listint_t **list, listint_t **taill, listint_t **shakr);
5+
void cocktail_sort_list(listint_t **list);
6+
7+
/**
8+
* swap_ahead - Swap a node in a listint_t doubly linked list
9+
* @list: Pointer to the head of a doubly linked list of integers.
10+
* @taill: Pointer to the taill of doubly linked list.
11+
* @shakr: Pointer to the current swapping node of the cocktail shakr algo.
12+
*/
13+
void swap_ahead(listint_t **list, listint_t **taill, listint_t **shakr)
14+
{
15+
listint_t *temp = (*shakr)->next;
16+
17+
if ((*shakr)->prev != NULL)
18+
(*shakr)->prev->next = temp;
19+
else
20+
*list = temp;
21+
temp->prev = (*shakr)->prev;
22+
(*shakr)->next = temp->next;
23+
if (temp->next != NULL)
24+
temp->next->prev = *shakr;
25+
else
26+
*taill = *shakr;
27+
(*shakr)->prev = temp;
28+
temp->next = *shakr;
29+
*shakr = temp;
30+
}
31+
32+
/**
33+
* swap_behind - Swap a node in a listint_t doubly-linked
34+
* @list: Pointer to the head of a doubly linked list of integers.
35+
* @taill: Pointer to the taill of the doubly linked list.
36+
* @shakr: Pointer to the current swapping node of the cocktail shakr algo.
37+
*/
38+
void swap_behind(listint_t **list, listint_t **taill, listint_t **shakr)
39+
{
40+
listint_t *temp = (*shakr)->prev;
41+
42+
if ((*shakr)->next != NULL)
43+
(*shakr)->next->prev = temp;
44+
else
45+
*taill = temp;
46+
temp->next = (*shakr)->next;
47+
(*shakr)->prev = temp->prev;
48+
if (temp->prev != NULL)
49+
temp->prev->next = *shakr;
50+
else
51+
*list = *shakr;
52+
(*shakr)->next = temp;
53+
temp->prev = *shakr;
54+
*shakr = temp;
55+
}
56+
57+
/**
58+
* cocktail_sort_list - Sort a listint_t doubly linked list of integers in
59+
* ascending order using the cocktail shakr algorithm.
60+
* @list: Pointer to the head of a listint_t doubly linked list.
61+
*/
62+
void cocktail_sort_list(listint_t **list)
63+
{
64+
listint_t *taill, *shakr;
65+
bool shaken_not_stirred = false;
66+
67+
if (list == NULL || *list == NULL || (*list)->next == NULL)
68+
return;
69+
70+
for (taill = *list; taill->next != NULL;)
71+
taill = taill->next;
72+
73+
while (shaken_not_stirred == false)
74+
{
75+
shaken_not_stirred = true;
76+
for (shakr = *list; shakr != taill; shakr = shakr->next)
77+
{
78+
if (shakr->n > shakr->next->n)
79+
{
80+
swap_ahead(list, &taill, &shakr);
81+
print_list((const listint_t *)*list);
82+
shaken_not_stirred = false;
83+
}
84+
}
85+
for (shakr = shakr->prev; shakr != *list;
86+
shakr = shakr->prev)
87+
{
88+
if (shakr->n < shakr->prev->n)
89+
{
90+
swap_behind(list, &taill, &shakr);
91+
print_list((const listint_t *)*list);
92+
shaken_not_stirred = false;
93+
}
94+
}
95+
}
96+
}

101-main.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include "sort.h"
4+
5+
/**
6+
* create_listint - Creates a doubly linked list from an array of integers
7+
*
8+
* @array: Array to convert to a doubly linked list
9+
* @size: Size of the array
10+
*
11+
* Return: Pointer to the first element of the created list. NULL on failure
12+
*/
13+
listint_t *create_listint(const int *array, size_t size)
14+
{
15+
listint_t *list;
16+
listint_t *node;
17+
int *tmp;
18+
19+
list = NULL;
20+
while (size--)
21+
{
22+
node = malloc(sizeof(*node));
23+
if (!node)
24+
return (NULL);
25+
tmp = (int *)&node->n;
26+
*tmp = array[size];
27+
node->next = list;
28+
node->prev = NULL;
29+
list = node;
30+
if (list->next)
31+
list->next->prev = list;
32+
}
33+
return (list);
34+
}
35+
36+
/**
37+
* main - Entry point
38+
*
39+
* Return: Always 0
40+
*/
41+
int main(void)
42+
{
43+
listint_t *list;
44+
int array[] = {19, 48, 99, 71, 13, 52, 96, 73, 86, 7};
45+
size_t n = sizeof(array) / sizeof(array[0]);
46+
47+
list = create_listint(array, n);
48+
if (!list)
49+
return (1);
50+
print_list(list);
51+
printf("\n");
52+
cocktail_sort_list(&list);
53+
printf("\n");
54+
print_list(list);
55+
return (0);
56+
}

102-counting_sort.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#include "sort.h"
2+
3+
/**
4+
* make_counting - make a counting array
5+
*
6+
* @max: max value in array
7+
* @size: size of array
8+
* @array: array of integers
9+
* Return: pointer to counting array
10+
*/
11+
12+
int *make_counting(int max, int size, int *array)
13+
{
14+
int *counting;
15+
int i;
16+
17+
counting = malloc(sizeof(int) * (max + 1));
18+
if (!counting)
19+
return (NULL);
20+
for (i = 0; i <= max; i++)
21+
counting[i] = 0;
22+
23+
i = 0;
24+
while (i < size)
25+
{
26+
counting[array[i]] += 1;
27+
i++;
28+
}
29+
i = 1;
30+
while (i <= max)
31+
{
32+
counting[i] = counting[i] + counting[i - 1];
33+
i++;
34+
}
35+
return (counting);
36+
}
37+
38+
/**
39+
* counting_sort - sort an array of integers in ascending order using the
40+
* counting sort algorithm
41+
* @array: array of integers
42+
* @size: size of array
43+
* Return: void
44+
*/
45+
46+
void counting_sort(int *array, size_t size)
47+
{
48+
int *counting, *sorted;
49+
int max, i, j;
50+
51+
if (!array || size < 2)
52+
return;
53+
max = array[0];
54+
for (i = 0; i < (int)size; i++)
55+
{
56+
if (array[i] > max)
57+
max = array[i];
58+
}
59+
counting = make_counting(max, size, array);
60+
if (!counting)
61+
return;
62+
63+
print_array(counting, max + 1);
64+
sorted = malloc(sizeof(int) * size);
65+
if (!sorted)
66+
{
67+
free(counting);
68+
return;
69+
}
70+
for (i = 0; i < (int)size; i++)
71+
{
72+
sorted[counting[array[i]] - 1] = array[i];
73+
counting[array[i]] -= 1;
74+
}
75+
for (j = 0; j < (int)size; j++)
76+
array[j] = sorted[j];
77+
free(counting);
78+
free(sorted);
79+
}

103-merge_sort.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include "sort.h"
2+
3+
void merge_sub(int *sub, int *buffr, size_t front, size_t mid,
4+
size_t back);
5+
void merge_recursive(int *sub, int *buffr, size_t front, size_t back);
6+
void merge_sort(int *array, size_t size);
7+
8+
/**
9+
* merge_sub - Sort a sub array of integers.
10+
* @sub: sub array of an array of integers to sort.
11+
* @buffr: buffer to store the sorted subarray.
12+
* @front: front index of the array.
13+
* @mid: middle index of the array.
14+
* @back: back index of the array.
15+
*/
16+
void merge_sub(int *sub, int *buffr, size_t front, size_t mid,
17+
size_t back)
18+
{
19+
size_t i, j, k = 0;
20+
21+
printf("Merging...\n[left]: ");
22+
print_array(sub + front, mid - front);
23+
24+
printf("[right]: ");
25+
print_array(sub + mid, back - mid);
26+
27+
for (i = front, j = mid; i < mid && j < back; k++)
28+
buffr[k] = (sub[i] < sub[j]) ? sub[i++] : sub[j++];
29+
for (; i < mid; i++)
30+
buffr[k++] = sub[i];
31+
for (; j < back; j++)
32+
buffr[k++] = sub[j];
33+
for (i = front, k = 0; i < back; i++)
34+
sub[i] = buffr[k++];
35+
36+
printf("[Done]: ");
37+
print_array(sub + front, back - front);
38+
}
39+
40+
/**
41+
* merge_recursive - Implement the merge sort algorithm through recursion.
42+
* @sub: A sub array of an array of integers to sort.
43+
* @buffr: A buffer to store the sorted result.
44+
* @front: The front index of the subarray.
45+
* @back: The back index of the subarray.
46+
*/
47+
void merge_recursive(int *sub, int *buffr, size_t front, size_t back)
48+
{
49+
size_t mid;
50+
51+
if (back - front > 1)
52+
{
53+
mid = front + (back - front) / 2;
54+
merge_recursive(sub, buffr, front, mid);
55+
merge_recursive(sub, buffr, mid, back);
56+
merge_sub(sub, buffr, front, mid, back);
57+
}
58+
}
59+
60+
/**
61+
* merge_sort - Sort an array of integers in ascending
62+
* @array: array of integers.
63+
* @size: size of the array.
64+
*
65+
* Description: an Implements the top-down merge sort algorithm.
66+
*/
67+
void merge_sort(int *array, size_t size)
68+
{
69+
int *buffr;
70+
71+
if (array == NULL || size < 2)
72+
return;
73+
74+
buffr = malloc(sizeof(int) * size);
75+
if (buffr == NULL)
76+
return;
77+
78+
merge_recursive(array, buffr, 0, size);
79+
80+
free(buffr);
81+
}

0 commit comments

Comments
 (0)