|
2 | 2 | #include <stdlib.h> |
3 | 3 | #include <string.h> |
4 | 4 |
|
| 5 | +/** |
| 6 | + * Definition for singly-linked list. |
| 7 | + * struct ListNode { |
| 8 | + * int val; |
| 9 | + * struct ListNode *next; |
| 10 | + * }; |
| 11 | + */ |
5 | 12 | struct ListNode { |
6 | 13 | int val; |
7 | 14 | struct ListNode *next; |
8 | 15 | }; |
9 | 16 |
|
10 | | -struct PriorityQueue { |
11 | | - struct ListNode **nodes; |
12 | | - int size; |
13 | | -}; |
14 | | - |
15 | 17 | static inline void swap(struct ListNode **a, struct ListNode **b) |
16 | 18 | { |
17 | | - struct ListNode *tmp = *a; |
| 19 | + struct ListNode *t = *a; |
18 | 20 | *a = *b; |
19 | | - *b = tmp; |
| 21 | + *b = t; |
20 | 22 | } |
21 | 23 |
|
22 | | -static inline int left(int i) { return i * 2 + 1; } |
23 | | -static inline int right(int i) { return left(i) + 1; } |
24 | | -static inline int parent(int i) { return (i - 1) / 2; } |
25 | | - |
26 | | -static void queue_dump(struct PriorityQueue *queue) |
| 24 | +static void min_heapify(struct ListNode **nodes, int size, int parent) |
27 | 25 | { |
28 | | - int i; |
29 | | - for (i = 0; i < queue->size; i++) { |
30 | | - printf("%d ", queue->nodes[i]->val); |
31 | | - } |
32 | | - printf("\n"); |
33 | | -} |
| 26 | + int i = parent; /* parent is the root */ |
| 27 | + int l = parent * 2 + 1; |
| 28 | + int r = parent * 2 + 2; |
34 | 29 |
|
35 | | -static void percolate_up(struct ListNode **nodes, int i) |
36 | | -{ |
37 | | - while (i >= 0 && nodes[parent(i)]->val > nodes[i]->val) { |
38 | | - swap(nodes + parent(i), nodes + i); |
39 | | - i = parent(i); |
| 30 | + if (l < size && nodes[l]->val < nodes[i]->val) { |
| 31 | + i = l; |
40 | 32 | } |
41 | | -} |
42 | 33 |
|
43 | | -static void percolate_down1(struct ListNode **nodes, int size, int child) |
44 | | -{ |
45 | | - int i, min; |
46 | | - for (i = child; i >= 0; i = parent(i)) { |
47 | | - if (right(i) < size) { |
48 | | - min = nodes[left(i)]->val < nodes[right(i)]->val ? left(i) : right(i); |
49 | | - } else { |
50 | | - min = left(i); |
51 | | - } |
52 | | - if (nodes[min]->val < nodes[i]->val) { |
53 | | - swap(nodes + min, nodes + i); |
54 | | - } else { |
55 | | - break; |
56 | | - } |
| 34 | + if (r < size && nodes[r]->val < nodes[i]->val) { |
| 35 | + i = r; |
57 | 36 | } |
58 | | -} |
59 | 37 |
|
60 | | -static void percolate_down2(struct ListNode **nodes, int size) |
61 | | -{ |
62 | | - int i, min; |
63 | | - for (i = 0; left(i) < size; i = min) { |
64 | | - if (right(i) < size) { |
65 | | - min = nodes[left(i)]->val < nodes[right(i)]->val ? left(i) : right(i); |
66 | | - } else { |
67 | | - min = left(i); |
68 | | - } |
69 | | - if (nodes[min]->val < nodes[i]->val) { |
70 | | - swap(nodes + min, nodes + i); |
71 | | - } else { |
72 | | - break; |
73 | | - } |
| 38 | + /* percolate up */ |
| 39 | + if (i != parent) { |
| 40 | + swap(&nodes[i], &nodes[parent]); |
| 41 | + min_heapify(nodes, size, i); |
74 | 42 | } |
75 | 43 | } |
76 | 44 |
|
77 | | -static void heap_build(struct PriorityQueue *queue) |
| 45 | +static void build_min_heap(struct ListNode **nodes, int size) |
78 | 46 | { |
79 | 47 | int i; |
80 | | - for (i = queue->size / 2 - 1; i > 0; i--) { |
81 | | - percolate_down1(queue->nodes, queue->size, i); |
82 | | - } |
83 | | -} |
84 | 48 |
|
85 | | -static void put(struct PriorityQueue *queue, struct ListNode *node) |
86 | | -{ |
87 | | - queue->nodes[queue->size++] = node; |
88 | | - percolate_up(queue->nodes, queue->size - 1); |
| 49 | + if (size <= 0) return; |
| 50 | + |
| 51 | + for (i = size / 2; i >= 0; i--) { |
| 52 | + min_heapify(nodes, size, i); |
| 53 | + } |
89 | 54 | } |
90 | 55 |
|
91 | | -static struct ListNode *get(struct PriorityQueue *queue) |
| 56 | +static struct ListNode *get(struct ListNode **nodes, int size) |
92 | 57 | { |
93 | | - int i; |
94 | | - struct ListNode *p = queue->nodes[0]; |
95 | | - swap(queue->nodes, queue->nodes + queue->size - 1); |
96 | | - queue->size--; |
97 | | - percolate_down2(queue->nodes, queue->size); |
| 58 | + struct ListNode *p = nodes[0]; |
| 59 | + nodes[0] = nodes[--size]; |
| 60 | + min_heapify(nodes, size, 0); |
98 | 61 | return p; |
99 | 62 | } |
100 | 63 |
|
101 | | -static struct PriorityQueue *init(int size) |
| 64 | +static void put(struct ListNode **nodes, int size, struct ListNode *n) |
102 | 65 | { |
103 | | - struct PriorityQueue *queue = malloc(sizeof(*queue)); |
104 | | - queue->nodes = malloc(size * sizeof(*queue->nodes)); |
105 | | - queue->size = 0; |
106 | | - return queue; |
| 66 | + nodes[size++] = n; |
| 67 | + build_min_heap(nodes, size); |
107 | 68 | } |
108 | 69 |
|
109 | | -static struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) |
| 70 | +struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) |
110 | 71 | { |
111 | | - if (listsSize == 0) { |
112 | | - return NULL; |
113 | | - } |
114 | | - |
115 | | - if (listsSize == 1) { |
116 | | - return lists[0]; |
117 | | - } |
118 | | - |
119 | | - int i; |
| 72 | + int i, size = 0; |
120 | 73 | struct ListNode dummy; |
121 | | - struct ListNode *prev; |
122 | | - struct PriorityQueue *queue = init(listsSize); |
123 | | - |
124 | | - dummy.next = NULL; |
125 | | - prev = &dummy; |
| 74 | + struct ListNode *p = &dummy; |
| 75 | + struct ListNode **nodes = malloc(listsSize * sizeof(struct ListNode)); |
126 | 76 |
|
127 | 77 | for (i = 0; i < listsSize; i++) { |
128 | 78 | if (lists[i] != NULL) { |
129 | | - put(queue, lists[i]); |
| 79 | + nodes[size++] = lists[i]; |
130 | 80 | } |
131 | 81 | } |
132 | | - heap_build(queue); |
133 | 82 |
|
134 | | - while (queue->size > 0) { |
135 | | - struct ListNode *n = get(queue); |
136 | | - prev->next = n; |
137 | | - prev = n; |
| 83 | + build_min_heap(nodes, size); |
| 84 | + |
| 85 | + while (size > 0) { |
| 86 | + struct ListNode *n = get(nodes, size); |
| 87 | + size--; |
| 88 | + p->next = n; |
| 89 | + p = p->next; |
138 | 90 | if (n->next != NULL) { |
139 | | - put(queue, n->next); |
| 91 | + put(nodes, size, n->next); |
| 92 | + size++; |
140 | 93 | } |
141 | 94 | n->next = NULL; |
142 | 95 | } |
|
0 commit comments