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 }
时间: 2024-11-04 12:46:42