LeetCode —— Merge k Sorted Lists

  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 }

 

posted @ 2015-06-16 23:11  Jabnih  阅读(205)  评论(0编辑  收藏  举报