106 } |
106 } |
107 |
107 |
108 return s; |
108 return s; |
109 } |
109 } |
110 |
110 |
111 int ucx_list_qsort_devide(UcxList** list, int l, int r, cmp_func f, void* d) { |
111 UcxList *ucx_list_sort_merge(int length, |
112 int i = l; |
112 UcxList* ls, UcxList* rs, UcxList* le, UcxList* re, |
113 int j = r - 1; |
113 cmp_func fnc, void* data) { |
114 void *p = list[r]->data; |
114 UcxList *sorted[length]; |
115 UcxList *b; |
115 UcxList *rc, *lc; |
116 |
116 |
117 do { |
117 lc = ls; rc = rs; |
118 while (i < r && f(list[i]->data, p, d) <= 0) i++; |
118 int n = 0; |
119 while (j > l && f(list[j]->data, p, d) >= 0) j--; |
119 while (lc != le && rc != re) { |
120 if (i < j) { |
120 if (fnc(lc->data, rc->data, data) <= 0) { |
121 b = list[i]; |
121 sorted[n] = lc; |
122 list[i] = list[j]; |
122 lc = lc->next; |
123 list[j] = b; |
123 } else { |
124 } |
124 sorted[n] = rc; |
125 } while (i < j); |
125 rc = rc->next; |
126 |
126 } |
127 if (f(list[i]->data, p, d) > 0) { |
127 n++; |
128 b = list[r]; |
128 } |
129 list[r] = list[i]; |
129 while (lc != le) { |
130 list[i] = b; |
130 sorted[n] = lc; |
131 } |
131 lc = lc->next; |
132 |
132 n++; |
133 return i; |
133 } |
134 } |
134 while (rc != re) { |
135 |
135 sorted[n] = rc; |
136 void ucx_list_qsort_sort(UcxList** list, int l, int r, cmp_func f, void* d) { |
136 rc = rc->next; |
137 if (l < r) { |
137 n++; |
138 int m = ucx_list_qsort_devide(list, l, r, f, d); |
138 } |
139 ucx_list_qsort_sort(list, l, m-1, f, d); |
139 |
140 ucx_list_qsort_sort(list, m+1, r, f, d); |
140 // Update pointer |
141 } |
141 for (int i = 0 ; i < length-1 ; i++) { |
|
142 sorted[i]->next = sorted[i+1]; |
|
143 } |
|
144 sorted[length-1]->next = NULL; |
|
145 |
|
146 return sorted[0]; |
142 } |
147 } |
143 |
148 |
144 UcxList *ucx_list_sort(UcxList *l, cmp_func fnc, void *data) { |
149 UcxList *ucx_list_sort(UcxList *l, cmp_func fnc, void *data) { |
145 if (l == NULL) { |
150 if (l == NULL) { |
146 return NULL; |
151 return NULL; |
147 } |
152 } |
148 size_t n = ucx_list_size(l); |
153 |
149 if (n == 1) { |
154 UcxList *lc; |
|
155 int ln = 1; |
|
156 |
|
157 UcxList *ls = l, *le; |
|
158 lc = ls; |
|
159 while (lc->next != NULL && fnc(lc->next->data, lc->data, data) > 0) { |
|
160 lc = lc->next; |
|
161 ln++; |
|
162 } |
|
163 le = lc->next; |
|
164 |
|
165 UcxList *rs = le, *re; |
|
166 if (rs == NULL) { |
|
167 return l; // this list is already sorted :) |
|
168 } else { |
|
169 UcxList *rc; |
|
170 int rn = 1; |
|
171 rc = rs; |
|
172 while (rc->next != NULL && fnc(rc->next->data, rc->data, data) > 0) { |
|
173 rc = rc->next; |
|
174 rn++; |
|
175 } |
|
176 re = rc->next; |
|
177 |
|
178 // Something left? Sort it! |
|
179 UcxList *remainder = re; |
|
180 size_t remainder_length = ucx_list_size(remainder); |
|
181 if (remainder != NULL) { |
|
182 remainder = ucx_list_sort(remainder, fnc, data); |
|
183 } |
|
184 |
|
185 // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them |
|
186 UcxList *sorted = ucx_list_sort_merge(ln+rn, |
|
187 ls, rs, le, re, |
|
188 fnc, data); |
|
189 |
|
190 // merge sorted list with (also sorted) remainder |
|
191 l = ucx_list_sort_merge(ln+rn+remainder_length, |
|
192 sorted, remainder, NULL, NULL, |
|
193 fnc, data); |
|
194 |
150 return l; |
195 return l; |
151 } |
196 } |
152 |
|
153 UcxList *entries[n]; |
|
154 entries[0] = l; |
|
155 for (int i = 1 ; i < n ; i++) { |
|
156 entries[i] = entries[i-1]->next; |
|
157 } |
|
158 |
|
159 ucx_list_qsort_sort(entries, 0, n-1, fnc, data); |
|
160 |
|
161 for (int i = 0 ; i < n-1 ; i++) { |
|
162 entries[i]->next = entries[i+1]; |
|
163 } |
|
164 entries[n-1]->next = NULL; |
|
165 |
|
166 return entries[0]; |
|
167 } |
197 } |
168 |
198 |
169 /* list specific functions */ |
199 /* list specific functions */ |
170 UcxList *ucx_list_remove(UcxList *l, UcxList *e) { |
200 UcxList *ucx_list_remove(UcxList *l, UcxList *e) { |
171 if (e == l) { |
201 if (e == l) { |