11 l = l->next; |
12 l = l->next; |
12 } |
13 } |
13 return ret; |
14 return ret; |
14 } |
15 } |
15 |
16 |
16 int ucx_list_equals(UcxList *l1, UcxList *l2, cmp_func fnc, void* data) { |
17 int ucx_list_equals(const UcxList *l1, const UcxList *l2, |
|
18 cmp_func fnc, void* data) { |
17 if (l1 == l2) return 1; |
19 if (l1 == l2) return 1; |
18 |
20 |
19 while (l1 != NULL && l2 != NULL) { |
21 while (l1 != NULL && l2 != NULL) { |
20 if (fnc == NULL) { |
22 if (fnc == NULL) { |
21 if (l1->data != l2->data) return 0; |
23 if (l1->data != l2->data) return 0; |
61 nl->next = l; |
63 nl->next = l; |
62 } |
64 } |
63 return nl; |
65 return nl; |
64 } |
66 } |
65 |
67 |
66 UcxList *ucx_list_concat(UcxList *l1, UcxList *l2) { |
68 UcxList *ucx_list_concat(UcxList *restrict l1, UcxList *restrict l2) { |
67 if (l1 == NULL) { |
69 if (l1 == NULL) { |
68 return l2; |
70 return l2; |
69 } else { |
71 } else { |
70 UcxList *last = ucx_list_last(l1); |
72 UcxList *last = ucx_list_last(l1); |
71 last->next = l2; |
73 last->next = l2; |
72 return l1; |
74 return l1; |
73 } |
75 } |
74 } |
76 } |
75 |
77 |
76 UcxList *ucx_list_last(UcxList *l) { |
78 UcxList *ucx_list_last(const UcxList *l) { |
77 if (l == NULL) return NULL; |
79 if (l == NULL) return NULL; |
78 |
80 |
79 UcxList *e = l; |
81 const UcxList *e = l; |
80 while (e->next != NULL) { |
82 while (e->next != NULL) { |
81 e = e->next; |
83 e = e->next; |
82 } |
84 } |
83 return e; |
85 return (UcxList*)e; |
84 } |
86 } |
85 |
87 |
86 UcxList *ucx_list_get(UcxList *l, int index) { |
88 UcxList *ucx_list_get(const UcxList *l, int index) { |
87 if (l == NULL) return NULL; |
89 if (l == NULL) return NULL; |
88 |
90 |
89 UcxList *e = l; |
91 const UcxList *e = l; |
90 while (e->next != NULL && index > 0) { |
92 while (e->next != NULL && index > 0) { |
91 e = e->next; |
93 e = e->next; |
92 index--; |
94 index--; |
93 } |
95 } |
94 |
96 |
95 return index == 0 ? e : NULL; |
97 return (UcxList*)(index == 0 ? e : NULL); |
96 } |
98 } |
97 |
99 |
98 size_t ucx_list_size(UcxList *l) { |
100 size_t ucx_list_size(const UcxList *l) { |
99 if (l == NULL) return 0; |
101 if (l == NULL) return 0; |
100 |
102 |
101 UcxList *e = l; |
103 const UcxList *e = l; |
102 size_t s = 1; |
104 size_t s = 1; |
103 while (e->next != NULL) { |
105 while (e->next != NULL) { |
104 e = e->next; |
106 e = e->next; |
105 s++; |
107 s++; |
106 } |
108 } |
107 |
109 |
108 return s; |
110 return s; |
109 } |
111 } |
110 |
112 |
111 UcxList *ucx_list_sort_merge(int length, |
113 UcxList *ucx_list_sort_merge(int length, |
112 UcxList* ls, UcxList* rs, UcxList* le, UcxList* re, |
114 UcxList* restrict ls, UcxList* restrict le, UcxList* restrict re, |
113 cmp_func fnc, void* data) { |
115 cmp_func fnc, void* data) { |
114 UcxList *sorted[length]; |
116 UcxList *sorted[length]; |
115 UcxList *rc, *lc; |
117 UcxList *rc, *lc; |
116 |
118 |
117 lc = ls; rc = rs; |
119 lc = ls; rc = le; |
118 int n = 0; |
120 int n = 0; |
119 while (lc != le && rc != re) { |
121 while (lc && lc != le && rc != re) { |
120 if (fnc(lc->data, rc->data, data) <= 0) { |
122 if (fnc(lc->data, rc->data, data) <= 0) { |
121 sorted[n] = lc; |
123 sorted[n] = lc; |
122 lc = lc->next; |
124 lc = lc->next; |
123 } else { |
125 } else { |
124 sorted[n] = rc; |
126 sorted[n] = rc; |
125 rc = rc->next; |
127 rc = rc->next; |
126 } |
128 } |
127 n++; |
129 n++; |
128 } |
130 } |
129 while (lc != le) { |
131 while (lc && lc != le) { |
130 sorted[n] = lc; |
132 sorted[n] = lc; |
131 lc = lc->next; |
133 lc = lc->next; |
132 n++; |
134 n++; |
133 } |
135 } |
134 while (rc != re) { |
136 while (rc && rc != re) { |
135 sorted[n] = rc; |
137 sorted[n] = rc; |
136 rc = rc->next; |
138 rc = rc->next; |
137 n++; |
139 n++; |
138 } |
140 } |
139 |
141 |
152 } |
154 } |
153 |
155 |
154 UcxList *lc; |
156 UcxList *lc; |
155 int ln = 1; |
157 int ln = 1; |
156 |
158 |
157 UcxList *ls = l, *le; |
159 UcxList *restrict ls = l, *restrict le, *restrict re; |
158 lc = ls; |
160 lc = ls; |
159 while (lc->next != NULL && fnc(lc->next->data, lc->data, data) > 0) { |
161 while (lc->next != NULL && fnc(lc->next->data, lc->data, data) > 0) { |
160 lc = lc->next; |
162 lc = lc->next; |
161 ln++; |
163 ln++; |
162 } |
164 } |
163 le = lc->next; |
165 le = lc->next; |
164 |
166 |
165 UcxList *rs = le, *re; |
167 if (le == NULL) { |
166 if (rs == NULL) { |
|
167 return l; // this list is already sorted :) |
168 return l; // this list is already sorted :) |
168 } else { |
169 } else { |
169 UcxList *rc; |
170 UcxList *rc; |
170 int rn = 1; |
171 int rn = 1; |
171 rc = rs; |
172 rc = le; |
172 while (rc->next != NULL && fnc(rc->next->data, rc->data, data) > 0) { |
173 while (rc->next != NULL && fnc(rc->next->data, rc->data, data) > 0) { |
173 rc = rc->next; |
174 rc = rc->next; |
174 rn++; |
175 rn++; |
175 } |
176 } |
176 re = rc->next; |
177 re = rc->next; |
182 remainder = ucx_list_sort(remainder, fnc, data); |
183 remainder = ucx_list_sort(remainder, fnc, data); |
183 } |
184 } |
184 |
185 |
185 // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them |
186 // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them |
186 UcxList *sorted = ucx_list_sort_merge(ln+rn, |
187 UcxList *sorted = ucx_list_sort_merge(ln+rn, |
187 ls, rs, le, re, |
188 ls, le, re, |
188 fnc, data); |
189 fnc, data); |
189 |
190 |
190 // merge sorted list with (also sorted) remainder |
191 // merge sorted list with (also sorted) remainder |
191 l = ucx_list_sort_merge(ln+rn+remainder_length, |
192 l = ucx_list_sort_merge(ln+rn+remainder_length, |
192 sorted, remainder, NULL, NULL, |
193 sorted, remainder, NULL, fnc, data); |
193 fnc, data); |
|
194 |
194 |
195 return l; |
195 return l; |
196 } |
196 } |
197 } |
197 } |
198 |
198 |