|
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 | + |
13 | 18 | /* Create an empty queue */
|
14 | 19 | struct list_head *q_new()
|
15 | 20 | {
|
@@ -75,6 +80,7 @@ bool q_insert_tail(struct list_head *head, char *s)
|
75 | 80 | free(new_node);
|
76 | 81 | return false;
|
77 | 82 | }
|
| 83 | + INIT_LIST_HEAD(&new_node->list); |
78 | 84 | list_add_tail(&new_node->list, head);
|
79 | 85 | return true;
|
80 | 86 | }
|
@@ -273,28 +279,136 @@ void q_reverseK(struct list_head *head, int k)
|
273 | 279 | }
|
274 | 280 |
|
275 | 281 | /* Sort elements of queue in ascending/descending order */
|
276 |
| -void q_sort(struct list_head *head, bool descend) {} |
| 282 | +void q_sort(struct list_head *head, bool descend) |
| 283 | +{ |
| 284 | + if (!head || list_empty(head) || head->next == head->prev) { |
| 285 | + return; |
| 286 | + } |
| 287 | + |
| 288 | + head->prev->next = NULL; |
| 289 | + struct list_head *sorted = merge_sort(head->next, descend); |
| 290 | + |
| 291 | + LIST_HEAD(tmp); |
| 292 | + list_splice_tail_init(sorted, &tmp); |
| 293 | + list_splice_tail_init(&tmp, head); |
| 294 | +} |
| 295 | + |
| 296 | +static struct list_head *merge_sort(struct list_head *head, bool descend) |
| 297 | +{ |
| 298 | + if (!head || !head->next) |
| 299 | + return head; |
| 300 | + |
| 301 | + struct list_head *slow = head, *fast = head->next; |
| 302 | + |
| 303 | + while (fast && fast->next) { |
| 304 | + slow = slow->next; |
| 305 | + fast = fast->next->next; |
| 306 | + } |
| 307 | + |
| 308 | + struct list_head *mid = slow->next; |
| 309 | + slow->next = NULL; |
| 310 | + |
| 311 | + struct list_head *left = merge_sort(head, descend); |
| 312 | + struct list_head *right = merge_sort(mid, descend); |
| 313 | + |
| 314 | + return merge(left, right, descend); |
| 315 | +} |
| 316 | + |
| 317 | +static struct list_head *merge(struct list_head *l1, |
| 318 | + struct list_head *l2, |
| 319 | + bool descend) |
| 320 | +{ |
| 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 | + |
| 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 | + } |
| 341 | + |
| 342 | + tail = tail->next; |
| 343 | + } |
| 344 | + |
| 345 | + tail->next = l1 ? l1 : l2; |
| 346 | + if (tail->next) |
| 347 | + tail->next->prev = tail; |
| 348 | + |
| 349 | + return dummy.next; |
| 350 | +} |
277 | 351 |
|
278 | 352 | /* Remove every node which has a node with a strictly less value anywhere to
|
279 | 353 | * the right side of it */
|
280 | 354 | int q_ascend(struct list_head *head)
|
281 | 355 | {
|
| 356 | + if (!head || list_empty(head) || head->next == head->prev) { |
| 357 | + return 0; |
| 358 | + } |
| 359 | + |
| 360 | + struct list_head *cur = head->prev, *prev_max = cur, *tmp; |
| 361 | + int count = 1; |
| 362 | + |
| 363 | + list_for_each_safe (cur, tmp, head) { |
| 364 | + element_t *e_cur = list_entry(cur, element_t, list); |
| 365 | + const element_t *e_max = list_entry(prev_max, element_t, list); |
| 366 | + |
| 367 | + if (strcmp(e_cur->value, e_max->value) >= 0) { |
| 368 | + prev_max = cur; |
| 369 | + count++; |
| 370 | + } else { |
| 371 | + list_del(cur); |
| 372 | + free(e_cur->value); |
| 373 | + free(e_cur); |
| 374 | + } |
| 375 | + } |
| 376 | + |
| 377 | + return count; |
282 | 378 | // https://leetcode.com/problems/remove-nodes-from-linked-list/
|
283 |
| - return 0; |
284 | 379 | }
|
285 | 380 |
|
286 | 381 | /* Remove every node which has a node with a strictly greater value anywhere to
|
287 | 382 | * the right side of it */
|
288 | 383 | int q_descend(struct list_head *head)
|
289 | 384 | {
|
290 |
| - // https://leetcode.com/problems/remove-nodes-from-linked-list/ |
291 |
| - return 0; |
| 385 | + if (!head || list_empty(head) || head->next == head->prev) { |
| 386 | + return 0; |
| 387 | + } |
| 388 | + |
| 389 | + struct list_head *cur = head->prev, *prev_min = cur, *tmp; |
| 390 | + int count = 1; |
| 391 | + |
| 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); |
| 395 | + |
| 396 | + if (strcmp(e_cur->value, e_min->value) <= 0) { |
| 397 | + prev_min = cur; |
| 398 | + count++; |
| 399 | + } else { |
| 400 | + list_del(cur); |
| 401 | + free(e_cur->value); |
| 402 | + free(e_cur); |
| 403 | + } |
| 404 | + } |
| 405 | + |
| 406 | + return count; |
292 | 407 | }
|
293 | 408 |
|
294 | 409 | /* Merge all the queues into one sorted queue, which is in ascending/descending
|
295 | 410 | * order */
|
296 | 411 | int q_merge(struct list_head *head, bool descend)
|
297 | 412 | {
|
298 |
| - // https://leetcode.com/problems/merge-k-sorted-lists/ |
299 | 413 | return 0;
|
300 | 414 | }
|
0 commit comments