*optimized list sorting function by using merge sorting.

This commit is contained in:
paladin-t 2016-02-02 10:53:28 +08:00
parent afbb9baf8a
commit 20e5016bb0
3 changed files with 81 additions and 14 deletions

View File

@ -1,3 +1,6 @@
Feb. 2 2016
Optimized list sorting function by using merge sorting
Jan. 31 2016 Jan. 31 2016
Ignored first frame name with the TRACE command Ignored first frame name with the TRACE command

View File

@ -2152,27 +2152,90 @@ unsigned int _ls_foreach(_ls_node_t* list, _ls_operation op) {
} }
_ls_node_t* _ls_sort(_ls_node_t** list, _ls_compare cmp) { _ls_node_t* _ls_sort(_ls_node_t** list, _ls_compare cmp) {
_ls_node_t* ptr = 0; /* Copyright 2001 Simon Tatham, http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c */
bool_t is_circular = false, is_double = false;
_ls_node_t* p, * q, * e, * tail, * oldhead;
int insize, nmerges, psize, qsize, i;
_ls_node_t* lst = 0; _ls_node_t* lst = 0;
void* tmp = 0;
mb_assert(list && cmp); mb_assert(list && cmp);
lst = *list; lst = *list;
lst = lst->next; if(lst) lst = lst->next;
for( ; lst; lst = lst->next) {
for(ptr = lst; ptr; ptr = ptr->next) { if(!lst)
if(cmp(lst->data, ptr->data) > 0) { return 0;
tmp = ptr->data;
ptr->data = lst->data; insize = 1;
lst->data = tmp;
} while(1) {
} p = lst;
oldhead = lst;
lst = 0;
tail = 0;
nmerges = 0;
while(p) {
nmerges++;
q = p;
psize = 0;
for(i = 0; i < insize; i++) {
psize++;
if(is_circular)
q = (q->next == oldhead ? 0 : q->next);
else
q = q->next;
if(!q) break;
} }
qsize = insize;
while(psize > 0 || (qsize > 0 && q)) {
if(psize == 0) {
e = q; q = q->next; qsize--;
if(is_circular && q == oldhead) q = 0;
} else if(qsize == 0 || !q) {
e = p; p = p->next; psize--;
if(is_circular && p == oldhead) p = 0;
} else if(cmp(p->data, q->data) <= 0) {
e = p; p = p->next; psize--;
if(is_circular && p == oldhead) p = 0;
} else {
e = q; q = q->next; qsize--;
if(is_circular && q == oldhead) q = 0;
}
if(tail)
tail->next = e;
else
lst = e;
if(is_double)
e->prev = tail;
tail = e;
}
p = q;
}
if(is_circular) {
tail->next = lst;
if(is_double)
lst->prev = tail;
} else {
tail->next = 0;
}
if(nmerges <= 1) {
(*list)->next = lst;
(*list)->prev = tail;
return *list; return *list;
} }
insize *= 2;
}
}
int _ls_count(_ls_node_t* list) { int _ls_count(_ls_node_t* list) {
union { void* p; unsigned u; } tmp; union { void* p; unsigned u; } tmp;
@ -2712,7 +2775,8 @@ char* mb_strupr(char* s) {
/** Unicode handling */ /** Unicode handling */
#ifdef MB_ENABLE_UNICODE #ifdef MB_ENABLE_UNICODE
int mb_uu_ischar(char* ch) { int mb_uu_ischar(char* ch) {
/* Determine whether a buffer is a UTF8 encoded character, and return _TAKEn bytes */ /* Copyright 2008-2009 Bjoern Hoehrmann, http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ */
/* Determine whether a buffer is a UTF8 encoded character, and return taken bytes */
#define _TAKE(__ch, __c, __r) do { __c = *__ch++; __r++; } while(0) #define _TAKE(__ch, __c, __r) do { __c = *__ch++; __r++; } while(0)
#define _COPY(__ch, __c, __r, __cp) do { _TAKE(__ch, __c, __r); __cp = (__cp << 6) | ((unsigned char)__c & 0x3Fu); } while(0) #define _COPY(__ch, __c, __r, __cp) do { _TAKE(__ch, __c, __r); __cp = (__cp << 6) | ((unsigned char)__c & 0x3Fu); } while(0)
#define _TRANS(__m, __cp, __g) do { __cp &= ((__g[(unsigned char)c] & __m) != 0); } while(0) #define _TRANS(__m, __cp, __g) do { __cp &= ((__g[(unsigned char)c] & __m) != 0); } while(0)

Binary file not shown.