Skip to content

Commit 070cc66

Browse files
authored
Merge pull request kelvins#245 from andersonhsporto/c-timsort
Add timsort implementation in ANSCI C
2 parents 902eef0 + 815b672 commit 070cc66

File tree

2 files changed

+130
-2
lines changed

2 files changed

+130
-2
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -3261,8 +3261,8 @@ In order to achieve greater coverage and encourage more people to contribute to
32613261
<tr>
32623262
<td><a href="https://en.wikipedia.org/wiki/Timsort">Timsort</a></td>
32633263
<td> <!-- C -->
3264-
<a href="./CONTRIBUTING.md">
3265-
<img align="center" height="25" src="./logos/github.svg" />
3264+
<a href="./src/c/Timsort.c">
3265+
<img align="center" height="25" src="./logos/c.svg" />
32663266
</a>
32673267
</td>
32683268
<td> <!-- C++ -->

src/c/Timsort.c

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#include <stdio.h>
2+
3+
const int THRESHOLD = 32;
4+
5+
int is_odd(int n) {
6+
return n & 1;
7+
}
8+
9+
int get_fmin(int a, int b) {
10+
if (a < b) {
11+
return a;
12+
}
13+
return b;
14+
}
15+
16+
int get_floor(int n) {
17+
return n / 2;
18+
}
19+
20+
void print_array(int array[], int size) {
21+
printf("[");
22+
for (int i = 0; i < size; i++) {
23+
printf("%d", array[i]);
24+
if (i != size - 1) {
25+
printf(", ");
26+
}
27+
}
28+
printf("]\n");
29+
}
30+
31+
int get_run_length(int size_of_array) {
32+
int run_length = size_of_array;
33+
int remainder = 0;
34+
35+
while (run_length >= THRESHOLD) {
36+
if (is_odd(run_length)) {
37+
remainder = 1;
38+
}
39+
run_length = get_floor(run_length / 2);
40+
}
41+
return run_length + remainder;
42+
}
43+
44+
void insertion_sort(int array[], int left_index, int right_index) {
45+
for (int i = left_index + 1; i <= right_index; i++) {
46+
int temp = array[i];
47+
int j = i - 1;
48+
while (j >= left_index && array[j] > temp) {
49+
array[j + 1] = array[j];
50+
j--;
51+
}
52+
array[j + 1] = temp;
53+
}
54+
}
55+
56+
void merge_runs(int array[], int left_index, int middle_index, int right_index) {
57+
int left_size = middle_index - left_index + 1;
58+
int right_size = right_index - middle_index;
59+
int left[left_size];
60+
int right[right_size];
61+
62+
for (int i = 0; i < left_size; i++) {
63+
left[i] = array[left_index + i];
64+
}
65+
for (int j = 0; j < right_size; j++) {
66+
right[j] = array[middle_index + 1 + j];
67+
}
68+
69+
int i = 0;
70+
int j = 0;
71+
int k = left_index;
72+
73+
while (i < left_size && j < right_size) {
74+
if (left[i] <= right[j]) {
75+
array[k] = left[i];
76+
i++;
77+
} else {
78+
array[k] = right[j];
79+
j++;
80+
}
81+
k++;
82+
}
83+
84+
while (i < left_size) {
85+
array[k] = left[i];
86+
i++;
87+
k++;
88+
}
89+
90+
while (j < right_size) {
91+
array[k] = right[j];
92+
j++;
93+
k++;
94+
}
95+
}
96+
97+
void timsort(int array[], int size) {
98+
int run_length = get_run_length(size);
99+
100+
for (int i = 0; i < size; i += run_length) {
101+
insertion_sort(array, i, get_fmin((i + run_length - 1), (size - 1)));
102+
}
103+
104+
for (int size_of_run = run_length; size_of_run < size; size_of_run *= 2) {
105+
for (int left_index = 0; left_index < size; left_index += 2 * size_of_run) {
106+
int middle_index = left_index + size_of_run - 1;
107+
int right_index = get_fmin((left_index + 2 * size_of_run - 1), (size - 1));
108+
merge_runs(array, left_index, middle_index, right_index);
109+
}
110+
}
111+
}
112+
113+
int main() {
114+
int array[] = { 5, 2, -2147483648, 1, 4, 5323, -1, 0, 10, 9, 8, 7, 6, 2147483647, 4, 3, 2 };
115+
int size = sizeof(array) / sizeof(array[0]);
116+
117+
printf("Original array:\t");
118+
print_array(array, size);
119+
120+
timsort(array, size);
121+
122+
printf("Sorted array:\t");
123+
print_array(array, size);
124+
return 0;
125+
}
126+
127+
128+

0 commit comments

Comments
 (0)