Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit cf2719c

Browse files
author
Leo Ma
committed
Use Priority queue
Signed-off-by: Leo Ma <begeekmyfriend@192.168.1.5>
1 parent 2022e95 commit cf2719c

File tree

1 file changed

+118
-19
lines changed

1 file changed

+118
-19
lines changed

023_merge_k_sorted_lists/merge_lists.c

Lines changed: 118 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,144 @@
11
#include <stdio.h>
22
#include <stdlib.h>
3-
#include <limits.h>
3+
#include <string.h>
44

55
struct ListNode {
66
int val;
77
struct ListNode *next;
88
};
99

10+
struct PriorityQueue {
11+
struct ListNode **nodes;
12+
int size;
13+
};
14+
15+
static inline void swap(struct ListNode **a, struct ListNode **b)
16+
{
17+
struct ListNode *tmp = *a;
18+
*a = *b;
19+
*b = tmp;
20+
}
21+
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)
27+
{
28+
int i;
29+
for (i = 0; i < queue->size; i++) {
30+
printf("%d ", queue->nodes[i]->val);
31+
}
32+
printf("\n");
33+
}
34+
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);
40+
}
41+
}
42+
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+
}
57+
}
58+
}
59+
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+
}
74+
}
75+
}
76+
77+
static void heap_build(struct PriorityQueue *queue)
78+
{
79+
int i;
80+
for (i = queue->size / 2 - 1; i > 0; i--) {
81+
percolate_down1(queue->nodes, queue->size, i);
82+
}
83+
}
84+
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);
89+
}
90+
91+
static struct ListNode *get(struct PriorityQueue *queue)
92+
{
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);
98+
return p;
99+
}
100+
101+
static struct PriorityQueue *init(int size)
102+
{
103+
struct PriorityQueue *queue = malloc(sizeof(*queue));
104+
queue->nodes = malloc(size * sizeof(*queue->nodes));
105+
queue->size = 0;
106+
return queue;
107+
}
108+
10109
static struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
11110
{
12111
if (listsSize == 0) {
13112
return NULL;
14113
}
114+
15115
if (listsSize == 1) {
16116
return lists[0];
17117
}
18118

19-
int i, index;
20-
struct ListNode dummy, *p, *prev;
119+
int i;
120+
struct ListNode dummy;
121+
struct ListNode *prev;
122+
struct PriorityQueue *queue = init(listsSize);
21123

22124
dummy.next = NULL;
23125
prev = &dummy;
24-
index = 0;
25-
while (index != -1) {
26-
int min = INT_MAX;
27-
index = -1;
28-
for (i = 0; i < listsSize; i++) {
29-
if (lists[i] != NULL && lists[i]->val < min) {
30-
min = lists[i]->val;
31-
index = i;
32-
}
126+
127+
for (i = 0; i < listsSize; i++) {
128+
if (lists[i] != NULL) {
129+
put(queue, lists[i]);
33130
}
131+
}
132+
heap_build(queue);
34133

35-
if (index != -1) {
36-
p = malloc(sizeof(*p));
37-
p->val = min;
38-
p->next = NULL;
39-
prev->next = p;
40-
prev = p;
41-
lists[index] = lists[index]->next;
134+
while (queue->size > 0) {
135+
struct ListNode *n = get(queue);
136+
prev->next = n;
137+
prev = n;
138+
if (n->next != NULL) {
139+
put(queue, n->next);
42140
}
141+
n->next = NULL;
43142
}
44143

45144
return dummy.next;

0 commit comments

Comments
 (0)