source: mainline/uspace/lib/c/generic/sort.c@ 549012c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 549012c was 549012c, checked in by Martin Decky <martin@…>, 15 years ago

port sorting functions from kernel to libc

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Copyright (c) 2005 Sergey Bondari
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32
33/**
34 * @file
35 * @brief Sorting functions.
36 *
37 * This files contains functions implementing several sorting
38 * algorithms (e.g. quick sort and bubble sort).
39 *
40 */
41
42#include <sort.h>
43#include <mem.h>
44#include <malloc.h>
45
46/** Bubble sort
47 *
48 * Apply generic bubble sort algorithm on supplied data,
49 * using pre-allocated buffer.
50 *
51 * @param data Pointer to data to be sorted.
52 * @param cnt Number of elements to be sorted.
53 * @param elem_size Size of one element.
54 * @param cmp Comparator function.
55 * @param arg 3rd argument passed to cmp.
56 * @param slot Pointer to scratch memory buffer
57 * elem_size bytes long.
58 *
59 */
60static void _bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
61 void *arg, void *slot)
62{
63 bool done = false;
64 void *tmp;
65
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 }
78 }
79}
80
81/** Quicksort
82 *
83 * Apply generic quicksort algorithm on supplied data,
84 * using pre-allocated buffers.
85 *
86 * @param data Pointer to data to be sorted.
87 * @param cnt Number of elements to be sorted.
88 * @param elem_size Size of one element.
89 * @param cmp Comparator function.
90 * @param arg 3rd argument passed to cmp.
91 * @param tmp Pointer to scratch memory buffer
92 * elem_size bytes long.
93 * @param pivot Pointer to scratch memory buffer
94 * elem_size bytes long.
95 *
96 */
97static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
98 void *arg, void *tmp, void *pivot)
99{
100 if (cnt > 4) {
101 size_t i = 0;
102 size_t j = cnt - 1;
103
104 memcpy(pivot, data, elem_size);
105
106 while (true) {
107 while ((cmp(data + i * elem_size, pivot, arg) < 0) && (i < cnt))
108 i++;
109
110 while ((cmp(data + j * elem_size, pivot, arg) >= 0) && (j > 0))
111 j--;
112
113 if (i < j) {
114 memcpy(tmp, data + i * elem_size, elem_size);
115 memcpy(data + i * elem_size, data + j * elem_size,
116 elem_size);
117 memcpy(data + j * elem_size, tmp, elem_size);
118 } else
119 break;
120 }
121
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);
125 } else
126 _bsort(data, cnt, elem_size, cmp, arg, tmp);
127}
128
129/** Bubble sort wrapper
130 *
131 * This is only a wrapper that takes care of memory
132 * allocations for storing the slot element for generic
133 * bubble sort algorithm.
134 *
135 * @param data Pointer to data to be sorted.
136 * @param cnt Number of elements to be sorted.
137 * @param elem_size Size of one element.
138 * @param cmp Comparator function.
139 * @param arg 3rd argument passed to cmp.
140 *
141 * @return True if sorting succeeded.
142 *
143 */
144bool bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
145{
146 void *slot = (void *) malloc(elem_size);
147 if (!slot)
148 return false;
149
150 _bsort(data, cnt, elem_size, cmp, arg, slot);
151
152 free(slot);
153
154 return true;
155}
156
157/** Quicksort wrapper
158 *
159 * This is only a wrapper that takes care of memory
160 * allocations for storing the pivot and temporary elements
161 * for generic quicksort algorithm.
162 *
163 * @param data Pointer to data to be sorted.
164 * @param cnt Number of elements to be sorted.
165 * @param elem_size Size of one element.
166 * @param cmp Comparator function.
167 * @param arg 3rd argument passed to cmp.
168 *
169 * @return True if sorting succeeded.
170 *
171 */
172bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
173{
174 void *tmp = (void *) malloc(elem_size);
175 if (!tmp)
176 return false;
177
178 void *pivot = (void *) malloc(elem_size);
179 if (!pivot) {
180 free(tmp);
181 return false;
182 }
183
184 _qsort(data, cnt, elem_size, cmp, arg, tmp, pivot);
185
186 free(pivot);
187 free(tmp);
188
189 return true;
190}
191
192/** @}
193 */
Note: See TracBrowser for help on using the repository browser.