From e83f15c6c5207945e2d0535e7bb9e5f5c1e65a8b Mon Sep 17 00:00:00 2001 From: Daniele Fucini Date: Fri, 20 Sep 2019 21:43:17 +0200 Subject: [PATCH] Improve quick sort --- C/projecteuler.c | 92 ++++++++++++++++++++++++++++++++++++++---------- C/projecteuler.h | 1 + 2 files changed, 74 insertions(+), 19 deletions(-) diff --git a/C/projecteuler.c b/C/projecteuler.c index 3f146f9..e9076c6 100644 --- a/C/projecteuler.c +++ b/C/projecteuler.c @@ -2,6 +2,8 @@ #include #include "projecteuler.h" +int partition(void **array, int l, int r, int (*cmp)(void *lv, void *rv)); + int is_prime(long int num) { int i, limit; @@ -129,29 +131,81 @@ int count_divisors(int n) return count; } -void quick_sort(void **array, int l, int r, int (*cmp)(void *lv, void *rv)) +void insertion_sort(void **array, int l, int r, int (*cmp)(void *lv, void *rv)) { int i, j; - void *pivot, *tmp; - - if (l >= r) return; - - pivot = array[l]; - i = l - 1; - j = r + 1; - - while (i < j) { - - while (cmp(array[++i], pivot) < 0); - while (cmp(array[--j], pivot) > 0); - - if (i < j) { + void *tmp; + + for(i = r; i > l; i--) + { + if(cmp(array[i], array[i-1]) < 0) + { tmp = array[i]; - array[i] = array[j]; - array[j] = tmp; + array[i] = array[i-1]; + array[i-1] = tmp; } } + for(i = l + 2; i <= r; i++) + { + tmp = array[i]; + j = i; - quick_sort(array, l, j, cmp); - quick_sort(array, j+1, r, cmp); + while(cmp(tmp, array[j-1]) < 0) + { + array[j] = array[j-1]; + j--; + } + + array[j] = tmp; + } +} + +int partition(void **array, int l, int r, int (*cmp)(void *lv, void *rv)) +{ + int i = l -1, j = r; + void *pivot, *tmp; + + pivot = array[r]; + + while(1) + { + while(cmp(array[++i], pivot) < 0); + while(cmp(array[--j], pivot) > 0) + { + if(j == l) + { + break; + } + } + + if(j <= i) + { + break; + } + + tmp = array[i]; + array[i] = array[j]; + array[j] = tmp; + } + + tmp = array[i]; + array[i] = array[r]; + array[r] = tmp; + + return i; +} + +void quick_sort(void **array, int l, int r, int (*cmp)(void *lv, void *rv)) +{ + int i; + + if(r - l <= 10) + { + insertion_sort(array, l, r, cmp); + return; + } + + i = partition(array, l, r, cmp); + quick_sort(array, l, i-1, cmp); + quick_sort(array, i+1, r, cmp); } diff --git a/C/projecteuler.h b/C/projecteuler.h index 806b4f2..b577090 100644 --- a/C/projecteuler.h +++ b/C/projecteuler.h @@ -7,6 +7,7 @@ long int lcm(long int a, long int b); long int gcd(long int a, long int b); int *sieve(int n); int count_divisors(int n); +void insertion_sort(void **array, int l, int r, int (*cmp)(void *lv, void *rv)); void quick_sort(void **array, int l, int r, int (*cmp)(void *lv, void *rv)); #endif