10
10
* cppcheck-suppress nullPointer
11
11
*/
12
12
13
- static struct list_head * merge_sort (struct list_head * head , bool descend );
14
- static struct list_head * merge (struct list_head * l1 ,
15
- struct list_head * l2 ,
16
- bool descend );
17
-
18
13
/* Create an empty queue */
19
14
struct list_head * q_new ()
20
15
{
@@ -166,38 +161,42 @@ bool q_delete_mid(struct list_head *head)
166
161
/* Delete all nodes that have duplicate string */
167
162
bool q_delete_dup (struct list_head * head )
168
163
{
169
- if (!head || list_empty (head )) {
164
+ if (!head || list_empty (head ))
170
165
return false;
171
- }
172
166
173
- struct list_head * cur = head -> next ;
167
+ struct list_head * cur , * next ;
174
168
bool deleted = false;
175
169
176
- while (cur != head || cur -> next != head ) {
177
- // compare between cur->value and next_cur->value7
178
- const element_t * node = list_entry (cur , element_t , list );
179
- const element_t * next_node = list_entry (cur -> next , element_t , list );
170
+ list_for_each_safe (cur , next , head ) {
171
+ element_t * node = list_entry (cur , element_t , list );
172
+
173
+ if (next != head ) {
174
+ const element_t * next_node = list_entry (next , element_t , list );
175
+
176
+ if (strcmp (node -> value , next_node -> value ) == 0 ) {
177
+ deleted = true;
178
+ const char * dup_value = node -> value ;
179
+ struct list_head * tmp ;
180
180
181
- if (strcmp (node -> value , next_node -> value ) == 0 ) {
182
- deleted = true;
183
- const char * dup_value = node -> value ;
184
- struct list_head * tmp ;
181
+ while (next != head &&
182
+ strcmp (list_entry (next , element_t , list )-> value ,
183
+ dup_value ) == 0 ) {
184
+ tmp = next -> next ;
185
+ list_del (next );
186
+ element_t * del_node = list_entry (next , element_t , list );
187
+ free (del_node -> value );
188
+ free (del_node );
189
+ next = tmp ;
190
+ }
185
191
186
- while (cur != head &&
187
- strcmp (list_entry (cur , element_t , list )-> value , dup_value )) {
188
192
tmp = cur -> next ;
189
193
list_del (cur );
190
- element_t * del_node = list_entry (cur , element_t , list );
191
- free (del_node -> value );
192
- free (del_node );
194
+ free (node -> value );
195
+ free (node );
193
196
cur = tmp ;
194
197
}
195
- } else {
196
- cur = cur -> next ;
197
198
}
198
199
}
199
-
200
- // https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/
201
200
return deleted ;
202
201
}
203
202
@@ -242,64 +241,77 @@ void q_reverse(struct list_head *head)
242
241
/* Reverse the nodes of the list k at a time */
243
242
void q_reverseK (struct list_head * head , int k )
244
243
{
245
- if (!head || list_empty (head ) || k <= 1 ) {
244
+ if (!head || list_empty (head ) || k <= 1 )
246
245
return ;
247
- }
248
246
249
- struct list_head * cur , * next ;
247
+ struct list_head * cur , * group_start , * next ;
250
248
int count = 0 ;
251
249
252
- list_for_each (cur , head ) {
250
+ list_for_each (cur , head )
253
251
count ++ ;
254
- }
255
252
256
- if (count < k ) {
253
+ if (count < k )
257
254
return ;
258
- }
259
255
260
256
cur = head -> next ;
261
257
262
258
while (count >= k ) {
263
- struct list_head * group_tail = cur ;
264
- int i = 0 ;
259
+ group_start = cur ;
260
+ struct list_head * prev_tail = group_start -> prev ;
265
261
266
- list_for_each_safe ( cur , next , head ) {
267
- if ( ++ i == k )
268
- break ;
269
- list_move_tail ( next , head ) ;
262
+ for ( int i = 0 ; i < k ; i ++ ) {
263
+ next = cur -> next ;
264
+ list_move ( cur , prev_tail ) ;
265
+ cur = next ;
270
266
}
271
267
272
- group_tail -> prev = cur -> prev ;
273
- cur -> prev -> next = group_tail ;
268
+ group_start -> next = cur ;
269
+ if (cur )
270
+ cur -> prev = group_start ;
274
271
275
- cur = group_tail -> next ;
276
272
count -= k ;
277
273
}
278
- return ;
279
274
}
280
275
281
276
/* Sort elements of queue in ascending/descending order */
282
- void q_sort (struct list_head * head , bool descend )
277
+ static struct list_head * merge (struct list_head * l1 ,
278
+ struct list_head * l2 ,
279
+ bool descend )
283
280
{
284
- if (!head || list_empty (head ) || head -> next == head -> prev ) {
285
- return ;
281
+ struct list_head dummy ;
282
+ struct list_head * tail = & dummy ;
283
+
284
+ while (l1 && l2 ) {
285
+ const element_t * e1 = list_entry (l1 , element_t , list );
286
+ const element_t * e2 = list_entry (l2 , element_t , list );
287
+
288
+ bool condition = descend ? (strcmp (e1 -> value , e2 -> value ) < 0 )
289
+ : (strcmp (e1 -> value , e2 -> value ) > 0 );
290
+
291
+ if (!condition || strcmp (e1 -> value , e2 -> value ) == 0 ) {
292
+ tail -> next = l1 ;
293
+ l1 = l1 -> next ;
294
+ } else {
295
+ tail -> next = l2 ;
296
+ l2 = l2 -> next ;
297
+ }
298
+
299
+ tail -> next -> prev = tail ;
300
+ tail = tail -> next ;
286
301
}
287
302
288
- head -> prev -> next = NULL ;
289
- struct list_head * sorted = merge_sort (head -> next , descend );
303
+ tail -> next = l1 ? l1 : l2 ;
304
+ if (tail -> next )
305
+ tail -> next -> prev = tail ;
290
306
291
- LIST_HEAD (tmp );
292
- list_splice_tail_init (sorted , & tmp );
293
- list_splice_tail_init (& tmp , head );
307
+ return dummy .next ;
294
308
}
295
-
296
309
static struct list_head * merge_sort (struct list_head * head , bool descend )
297
310
{
298
311
if (!head || !head -> next )
299
312
return head ;
300
313
301
314
struct list_head * slow = head , * fast = head -> next ;
302
-
303
315
while (fast && fast -> next ) {
304
316
slow = slow -> next ;
305
317
fast = fast -> next -> next ;
@@ -314,39 +326,30 @@ static struct list_head *merge_sort(struct list_head *head, bool descend)
314
326
return merge (left , right , descend );
315
327
}
316
328
317
- static struct list_head * merge (struct list_head * l1 ,
318
- struct list_head * l2 ,
319
- bool descend )
329
+ void q_sort (struct list_head * head , bool descend )
320
330
{
321
- struct list_head dummy ;
322
- struct list_head * tail = & dummy ;
323
- dummy .next = NULL ;
324
-
325
- while (l1 && l2 ) {
326
- const element_t * e1 = list_entry (l1 , element_t , list );
327
- const element_t * e2 = list_entry (l2 , element_t , list );
328
-
329
- bool condition = descend ? (strcmp (e1 -> value , e2 -> value ) > 0 )
330
- : (strcmp (e1 -> value , e2 -> value ) < 0 );
331
+ if (!head || list_empty (head ) || head -> next == head )
332
+ return ;
331
333
332
- if (condition ) {
333
- tail -> next = l1 ;
334
- l1 -> prev = tail ;
335
- l1 = l1 -> next ;
336
- } else {
337
- tail -> next = l2 ;
338
- l2 -> prev = tail ;
339
- l2 = l2 -> next ;
340
- }
334
+ head -> prev -> next = NULL ;
335
+ struct list_head * sorted = merge_sort (head -> next , descend );
341
336
342
- tail = tail -> next ;
337
+ if (!sorted ) {
338
+ head -> next = head ;
339
+ head -> prev = head ;
340
+ return ;
343
341
}
344
342
345
- tail -> next = l1 ? l1 : l2 ;
346
- if (tail -> next )
347
- tail -> next -> prev = tail ;
343
+ struct list_head * cur = sorted , * prev = head ;
344
+ while (cur ) {
345
+ cur -> prev = prev ;
346
+ prev -> next = cur ;
347
+ prev = cur ;
348
+ cur = cur -> next ;
349
+ }
348
350
349
- return dummy .next ;
351
+ prev -> next = head ;
352
+ head -> prev = prev ;
350
353
}
351
354
352
355
/* Remove every node which has a node with a strictly less value anywhere to
@@ -382,25 +385,28 @@ int q_ascend(struct list_head *head)
382
385
* the right side of it */
383
386
int q_descend (struct list_head * head )
384
387
{
385
- if (!head || list_empty (head ) || head -> next == head -> prev ) {
388
+ if (!head || list_empty (head ))
386
389
return 0 ;
387
- }
388
390
389
- struct list_head * cur = head -> prev , * prev_min = cur , * tmp ;
391
+ struct list_head * cur = head -> prev ;
392
+ struct list_head * prev = cur -> prev ;
393
+ const element_t * max_elem = list_entry (cur , element_t , list );
390
394
int count = 1 ;
391
395
392
- list_for_each_safe ( cur , tmp , head ) {
393
- element_t * e_cur = list_entry (cur , element_t , list );
394
- const element_t * e_min = list_entry ( prev_min , element_t , list ) ;
396
+ while ( prev != head ) {
397
+ element_t * e = list_entry (prev , element_t , list );
398
+ struct list_head * tmp = prev -> prev ;
395
399
396
- if (strcmp (e_cur -> value , e_min -> value ) <= 0 ) {
397
- prev_min = cur ;
398
- count ++ ;
400
+ if (strcmp (e -> value , max_elem -> value ) < 0 ) {
401
+ list_del (prev );
402
+ free (e -> value );
403
+ free (e );
399
404
} else {
400
- list_del (cur );
401
- free (e_cur -> value );
402
- free (e_cur );
405
+ max_elem = e ;
406
+ count ++ ;
403
407
}
408
+
409
+ prev = tmp ;
404
410
}
405
411
406
412
return count ;
0 commit comments