Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/sort.c

    rc6c49de r549012c  
    3636 *
    3737 * This files contains functions implementing several sorting
    38  * algorithms (e.g. quick sort and gnome sort).
     38 * algorithms (e.g. quick sort and bubble sort).
    3939 *
    4040 */
     
    4444#include <malloc.h>
    4545
    46 /** Immediate buffer size.
     46/** Bubble sort
    4747 *
    48  * For small buffer sizes avoid doing malloc()
    49  * and use the stack.
    50  *
    51  */
    52 #define IBUF_SIZE  32
    53 
    54 /** Array accessor.
    55  *
    56  */
    57 #define INDEX(buf, i, elem_size)  ((buf) + (i) * (elem_size))
    58 
    59 /** Gnome sort
    60  *
    61  * Apply generic gnome sort algorithm on supplied data,
     48 * Apply generic bubble sort algorithm on supplied data,
    6249 * using pre-allocated buffer.
    6350 *
     
    7158 *
    7259 */
    73 static void _gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
     60static void _bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
    7461    void *arg, void *slot)
    7562{
    76         size_t i = 0;
     63        bool done = false;
     64        void *tmp;
    7765       
    78         while (i < cnt) {
    79                 if ((i != 0) &&
    80                     (cmp(INDEX(data, i, elem_size),
    81                     INDEX(data, i - 1, elem_size), arg) == -1)) {
    82                         memcpy(slot, INDEX(data, i, elem_size), elem_size);
    83                         memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size),
    84                             elem_size);
    85                         memcpy(INDEX(data, i - 1, elem_size), slot, elem_size);
    86                         i--;
    87                 } else
    88                         i++;
     66        while (!done) {
     67                done = true;
     68               
     69                for (tmp = data; tmp < data + elem_size * (cnt - 1);
     70                    tmp = tmp + elem_size) {
     71                        if (cmp(tmp, tmp + elem_size, arg) == 1) {
     72                                memcpy(slot, tmp, elem_size);
     73                                memcpy(tmp, tmp + elem_size, elem_size);
     74                                memcpy(tmp + elem_size, slot, elem_size);
     75                                done = false;
     76                        }
     77                }
    8978        }
    9079}
     
    10089 * @param cmp       Comparator function.
    10190 * @param arg       3rd argument passed to cmp.
    102  * @param slot      Pointer to scratch memory buffer
     91 * @param tmp       Pointer to scratch memory buffer
    10392 *                  elem_size bytes long.
    10493 * @param pivot     Pointer to scratch memory buffer
     
    10796 */
    10897static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
    109     void *arg, void *slot, void *pivot)
     98    void *arg, void *tmp, void *pivot)
    11099{
    111100        if (cnt > 4) {
     
    116105               
    117106                while (true) {
    118                         while ((cmp(INDEX(data, i, elem_size), pivot, arg) < 0) && (i < cnt))
     107                        while ((cmp(data + i * elem_size, pivot, arg) < 0) && (i < cnt))
    119108                                i++;
    120109                       
    121                         while ((cmp(INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0))
     110                        while ((cmp(data + j * elem_size, pivot, arg) >= 0) && (j > 0))
    122111                                j--;
    123112                       
    124113                        if (i < j) {
    125                                 memcpy(slot, INDEX(data, i, elem_size), elem_size);
    126                                 memcpy(INDEX(data, i, elem_size), INDEX(data, j, elem_size),
     114                                memcpy(tmp, data + i * elem_size, elem_size);
     115                                memcpy(data + i * elem_size, data + j * elem_size,
    127116                                    elem_size);
    128                                 memcpy(INDEX(data, j, elem_size), slot, elem_size);
     117                                memcpy(data + j * elem_size, tmp, elem_size);
    129118                        } else
    130119                                break;
    131120                }
    132121               
    133                 _qsort(data, j + 1, elem_size, cmp, arg, slot, pivot);
    134                 _qsort(INDEX(data, j + 1, elem_size), cnt - j - 1, elem_size,
    135                     cmp, arg, slot, pivot);
     122                _qsort(data, j + 1, elem_size, cmp, arg, tmp, pivot);
     123                _qsort(data + (j + 1) * elem_size, cnt - j - 1, elem_size,
     124                    cmp, arg, tmp, pivot);
    136125        } else
    137                 _gsort(data, cnt, elem_size, cmp, arg, slot);
     126                _bsort(data, cnt, elem_size, cmp, arg, tmp);
    138127}
    139128
    140 /** Gnome sort wrapper
     129/** Bubble sort wrapper
    141130 *
    142131 * This is only a wrapper that takes care of memory
    143132 * allocations for storing the slot element for generic
    144  * gnome sort algorithm.
     133 * bubble sort algorithm.
    145134 *
    146135 * @param data      Pointer to data to be sorted.
     
    153142 *
    154143 */
    155 bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
     144bool bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
    156145{
    157         uint8_t ibuf_slot[IBUF_SIZE];
    158         void *slot;
     146        void *slot = (void *) malloc(elem_size);
     147        if (!slot)
     148                return false;
    159149       
    160         if (elem_size > IBUF_SIZE) {
    161                 slot = (void *) malloc(elem_size);
    162                 if (!slot)
    163                         return false;
    164         } else
    165                 slot = (void *) ibuf_slot;
     150        _bsort(data, cnt, elem_size, cmp, arg, slot);
    166151       
    167         _gsort(data, cnt, elem_size, cmp, arg, slot);
    168        
    169         if (elem_size > IBUF_SIZE)
    170                 free(slot);
     152        free(slot);
    171153       
    172154        return true;
     
    190172bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
    191173{
    192         uint8_t ibuf_slot[IBUF_SIZE];
    193         uint8_t ibuf_pivot[IBUF_SIZE];
    194         void *slot;
    195         void *pivot;
     174        void *tmp = (void *) malloc(elem_size);
     175        if (!tmp)
     176                return false;
    196177       
    197         if (elem_size > IBUF_SIZE) {
    198                 slot = (void *) malloc(elem_size);
    199                 if (!slot)
    200                         return false;
    201                
    202                 pivot = (void *) malloc(elem_size);
    203                 if (!pivot) {
    204                         free(slot);
    205                         return false;
    206                 }
    207         } else {
    208                 slot = (void *) ibuf_slot;
    209                 pivot = (void *) ibuf_pivot;
     178        void *pivot = (void *) malloc(elem_size);
     179        if (!pivot) {
     180                free(tmp);
     181                return false;
    210182        }
    211183       
    212         _qsort(data, cnt, elem_size, cmp, arg, slot, pivot);
     184        _qsort(data, cnt, elem_size, cmp, arg, tmp, pivot);
    213185       
    214         if (elem_size > IBUF_SIZE) {
    215                 free(pivot);
    216                 free(slot);
    217         }
     186        free(pivot);
     187        free(tmp);
    218188       
    219189        return true;
Note: See TracChangeset for help on using the changeset viewer.