1 /*
2 ** 算法的思路:
3 ** 1.将k个链表的首元素进行建堆
4 ** 2.从堆中取出最小的元素,放到链表中
5 ** 3.如果取出元素的有后续的元素,则放入堆中,若没有则转步骤2,直到堆为空
6 */
7
8
9 #include <stdio.h>
10
11
12 struct ListNode
13 {
14 int val;
15 struct ListNode *next;
16 };
17
18
19 #define PARENT(i) (((i)-1)/2)
20 #define LEFT(i) ((i)*2+1)
21 #define RIGHT(i) ((i)*2+2)
22
23 typedef struct ListNode * ListNodePointer;
24
25
26 void MinHeapify(ListNodePointer lists[], int nListSize, int nParentIndex );
27 void BuildMinHeap(ListNodePointer lists[], int nListSize );
28 ListNodePointer ExtractMin( ListNodePointer lists[], int *pListSize );
29 void InsertHeap(ListNodePointer lists[], int *pListSize, ListNodePointer pNode );
30 struct ListNode* mergeKLists(struct ListNode** lists, int listsSize);
31
32
33
34 int main(int argc, char const *argv[])
35 {
36
37 struct ListNode list[2] = {{.next=NULL,.val=2}, {.next=NULL, .val=-1}};
38 ListNodePointer pListPointerArray[3] = {&list[0], NULL, &list[1]};
39
40 ListNodePointer header = mergeKLists(pListPointerArray, 3);
41
42 ListNodePointer pList = header;
43 while( NULL != pList )
44 {
45 printf("%d ", pList->val);
46 pList = pList->next;
47 }
48 printf("\n");
49
50 return 0;
51 }
52
53
54
55 void MinHeapify(ListNodePointer lists[], int nListSize, int nParentIndex )
56 {
57
58 int nLeftIndex; //左节点下标
59 int nRightIndex; //右节点下标
60 int nMinIndex; //最小节点下标
61 ListNodePointer pNodePtrTmp;
62
63 do
64 {
65 nLeftIndex = LEFT(nParentIndex);
66 nRightIndex = RIGHT(nParentIndex);
67 nMinIndex = nParentIndex;
68
69 if ( nLeftIndex < nListSize && lists[nLeftIndex]->val < lists[nMinIndex]->val )
70 {
71 nMinIndex = nLeftIndex;
72 }
73
74 if ( nRightIndex < nListSize && lists[nRightIndex]->val < lists[nMinIndex]->val )
75 {
76 nMinIndex = nRightIndex;
77 }
78
79 if ( nMinIndex != nParentIndex )
80 {
81 pNodePtrTmp = lists[nMinIndex];
82 lists[nMinIndex] = lists[nParentIndex];
83 lists[nParentIndex] = pNodePtrTmp;
84
85 nParentIndex = nMinIndex;
86
87 }else
88 {
89 break;
90 }
91
92 }while( 1 );
93 }
94
95 //建堆
96 void BuildMinHeap(ListNodePointer lists[], int nListSize )
97 {
98
99 int i;
100 for ( i = nListSize/2; i >= 0; i-- )
101 {
102 MinHeapify(lists, nListSize, i);
103 }
104 }
105
106 //从堆中取出最小的元素
107 ListNodePointer ExtractMin( ListNodePointer lists[], int *pListSize )
108 {
109
110 ListNodePointer pMinNode = lists[0];
111
112 (*pListSize)--;
113 lists[0] = lists[*pListSize];
114
115 MinHeapify(lists, *pListSize, 0);
116
117 return pMinNode;
118 }
119
120 //向堆中添加元素
121 void InsertHeap(ListNodePointer lists[], int *pListSize, ListNodePointer pNode )
122 {
123
124 int nCurNodeIndex = *pListSize;
125 int nParentIndex = PARENT(nCurNodeIndex);
126 ListNodePointer pNodePtrTmp;
127
128 lists[nCurNodeIndex] = pNode;
129 (*pListSize)++;
130
131 while ( nCurNodeIndex > 0 && lists[nParentIndex]->val > lists[nCurNodeIndex]->val )
132 {
133 pNodePtrTmp = lists[nParentIndex];
134 lists[nParentIndex] = lists[nCurNodeIndex];
135 lists[nCurNodeIndex] = pNodePtrTmp;
136
137 nCurNodeIndex = nParentIndex;
138 nParentIndex = PARENT(nCurNodeIndex);
139 }
140 }
141
142
143 struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
144 {
145
146
147 ListNodePointer *pListPointerArray = (ListNodePointer *) malloc( sizeof(ListNodePointer)*listsSize );
148 struct ListNode header = {.next=NULL};
149 ListNodePointer pTail = NULL;
150
151 int i;
152 int nHeapSize = 0;
153
154 for( i=0; i<listsSize; i++ )
155 {
156 if ( lists[i] != NULL )
157 {
158 pListPointerArray[nHeapSize] = lists[i];
159 nHeapSize++;
160 }
161 }
162
163 if ( nHeapSize == 0 )
164 {
165 return NULL;
166 }
167
168 BuildMinHeap(pListPointerArray, nHeapSize);
169
170 //这里为预处理
171 header.next = ExtractMin(pListPointerArray, &nHeapSize);
172 pTail = header.next;
173 if ( NULL != pTail && pTail->next != NULL )
174 {
175 InsertHeap(pListPointerArray, &nHeapSize, pTail->next );
176 }
177
178 while( nHeapSize != 0 )
179 {
180 pTail->next = ExtractMin(pListPointerArray, &nHeapSize);
181
182 pTail = pTail->next;
183
184 if ( NULL != pTail && NULL != pTail->next )
185 {
186 InsertHeap(pListPointerArray, &nHeapSize, pTail->next );
187 }
188 }
189
190 free(pListPointerArray);
191
192 return header.next;
193 }