From d3caad90c98a5c7f3ce9be79500541b44628b125 Mon Sep 17 00:00:00 2001 From: "bernard.xiong@gmail.com" Date: Sun, 31 Oct 2010 22:22:28 +0000 Subject: [PATCH] add qsort implementation. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1036 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/libc/minilibc/qsort.c | 46 ++++++++++++++++++++++++++++ components/libc/minilibc/stdlib.h | 4 +++ components/libc/minilibc/sys/types.h | 1 + 3 files changed, 51 insertions(+) create mode 100644 components/libc/minilibc/qsort.c diff --git a/components/libc/minilibc/qsort.c b/components/libc/minilibc/qsort.c new file mode 100644 index 000000000..624005713 --- /dev/null +++ b/components/libc/minilibc/qsort.c @@ -0,0 +1,46 @@ +#include +#include + +#include + +static void exch(char* base,size_t size,size_t a,size_t b) { + char* x=base+a*size; + char* y=base+b*size; + while (size) { + char z=*x; + *x=*y; + *y=z; + --size; ++x; ++y; + } +} + +/* Quicksort with 3-way partitioning, ala Sedgewick */ +/* Blame him for the scary variable names */ +/* http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf */ +static void quicksort(char* base,size_t size,ssize_t l,ssize_t r, + int (*compar)(const void*,const void*)) { + ssize_t i=l-1, j=r, p=l-1, q=r, k; + char* v=base+r*size; + if (r<=l) return; + for (;;) { + while (++i != r && compar(base+i*size,v)<0) ; + while (compar(v,base+(--j)*size)<0) if (j == l) break; + if (i >= j) break; + exch(base,size,i,j); + if (compar(base+i*size,v)==0) exch(base,size,++p,i); + if (compar(v,base+j*size)==0) exch(base,size,j,--q); + } + exch(base,size,i,r); j = i-1; ++i; + for (k=l; kq; k--, i++) exch(base,size,i,k); + quicksort(base,size,l,j,compar); + quicksort(base,size,i,r,compar); +} + +void qsort(void* base,size_t nmemb,size_t size,int (*compar)(const void*,const void*)) { + /* check for integer overflows */ + if (nmemb >= (((size_t)-1)>>1) || + size >= (((size_t)-1)>>1)) return; + if (nmemb>1) + quicksort(base,size,0,nmemb-1,compar); +} diff --git a/components/libc/minilibc/stdlib.h b/components/libc/minilibc/stdlib.h index 93c9b19b5..e91a17608 100644 --- a/components/libc/minilibc/stdlib.h +++ b/components/libc/minilibc/stdlib.h @@ -15,6 +15,8 @@ #ifndef __STDLIB_H__ #define __STDLIB_H__ +#include + #if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC) int atoi(const char *nptr); #endif @@ -28,4 +30,6 @@ int rand(void); int rand_r(unsigned int *seed); void srand(unsigned int seed); +void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); + #endif diff --git a/components/libc/minilibc/sys/types.h b/components/libc/minilibc/sys/types.h index fa0a23663..a2dbee525 100644 --- a/components/libc/minilibc/sys/types.h +++ b/components/libc/minilibc/sys/types.h @@ -5,6 +5,7 @@ typedef long off_t; typedef rt_size_t size_t; +typedef signed long ssize_t; /* Used for a count of bytes or an error indication. */ typedef rt_uint8_t u_char; typedef rt_uint16_t u_short; -- GitLab