1 /*
2 本程序说明:3
4 链表排序各种方法(快速排序)5
6 参考链接:7 http://blog.csdn.net/u012658346/article/details/51141288
8 http://www.jb51.net/article/37300.htm
9
10 */
11 #include
12 using namespacestd;13
14
15 //definition for singly-linked list.
16 template
17 structListNode18 {19 T val;20 ListNode*next;21 ListNode(T x) : val(x), next(NULL) {}22 };23
24 //链表结点构造
25 template
26 ListNode*create_list_node(T val)27 {28 ListNode* pNode = new ListNode(val);29 returnpNode;30 }31
32 //链表结点连接
33 template
34 void connect_list_node(ListNode* pCur, ListNode*pNext)35 {36 pCur->next =pNext;37 }38
39 //销毁单个节点(其实用这个更好,不会出现空悬指针)
40 template
41 void destory_Node(ListNode**ppNode)42 {43 if(*ppNode !=NULL)44 delete *ppNode;45 *ppNode =NULL;46 }47
48 //链表销毁(注意,除头节点外,其他节点均变成了空悬指针)
49 template
50 void destory_list(ListNode**ppHead)51 {52 ListNode** cur =ppHead;53 while(*cur !=NULL)54 {55 ListNode* tmp = (*cur)->next;//保存下一个节点
56 delete *cur;57 *cur =NULL;58 *cur =tmp;59 }60 }61
62 //链表打印
63 template
64 void print_list(ListNode*pHead)65 {66 ListNode* cur =pHead;67 while(cur !=NULL)68 {69 cout<< cur->val <next;71 }72 cout<
75 //链表快速排序
76 template
77 classList_qsort78 {79 private:80 //划分,使左边小于头结点元素,右边大于等于头结点元素
81 ListNode* list_partion(ListNode* pBegin,ListNode*pEnd)82 {83 if(pBegin == pEnd || pBegin->next ==NULL)84 returnpBegin;85
86 ListNode* pSlow=pBegin;87 ListNode* pFast=pBegin;88 ListNode* pKey=new ListNode(pBegin->val);//只为了保存用于比较的val
89 while(pFast !=pEnd)90 {91
92 if(pFast->val < pKey->val)93 {94 pSlow = pSlow->next;95 swap(pSlow->val,pFast->val);96 }97 pFast = pFast->next;98 }99
100 swap(pSlow->val,pBegin->val);101 delete pKey;//释放pKey
102 returnpSlow;103 }104 //排序辅助函数
105 void _list_qsort(ListNode* pBegin,ListNode*pEnd)106 {107 if(pBegin == pEnd || NULL == pBegin->next)108 return;109 ListNode* mid=list_partion(pBegin,pEnd);110 _list_qsort(pBegin,mid);111 _list_qsort(mid->next,pEnd);112 }113 public:114 //排序入口函数(版本1:传值)
115 void list_qsort(ListNode*pHead)116 {117 if(pHead == NULL || pHead->next ==NULL)118 return;119 _list_qsort(pHead,NULL);120
121 }122
123 /*
124 //排序入口函数(版本2:传指针)125 void list_qsort(ListNode** ppHead)126 {127 if(*ppHead == NULL || (*ppHead)->next ==NULL)128 return;129 _list_qsort(*ppHead,NULL);130 }131 */
132
133 /*
134 //排序入口函数(版本3:传引用)135 void list_qsort(ListNode*& pHead)136 {137 if(NULL == pHead || NULL == pHead->next )138 return;139 _list_qsort(pHead,NULL);140 }141 */
142 };143
144 //链表插入排序
145 template
146 classList_insertion_sort147 {148
149 //版本1:指针的指针
150 private:151 //对于待插入的节点,选择合适的位置插入
152 void _list_insert_sort(ListNode** ppNode, ListNode*pNode)153 {154 ListNode* prev =NULL;155 ListNode* cur =NULL;156
157 if(pNode->val < (*ppNode)->val)158 {159 pNode->next = *ppNode;160 (*ppNode) =pNode;161 return;162 }163
164 cur = *ppNode;165
166 while(cur !=NULL)167 {168 if(pNode->val < cur->val)169 break;170
171 prev =cur;172 cur = cur->next;173 }174
175 pNode->next = cur;//或pNode->next = prev->next
176 prev->next =pNode;177 return;178 }179 public:180 //首先遍历节点,一边是排序好的节点,一边是待排序的节点
181 void list_insert_sort(ListNode**ppNode)182 {183 ListNode* prev =NULL;184 ListNode* cur =NULL;185
186 if(NULL == ppNode || NULL == *ppNode)187 return;188
189 cur = (*ppNode)->next;190 (*ppNode)->next =NULL;191
192 while(cur !=NULL)193 {194 prev =cur;195 cur = cur->next;196 _list_insert_sort(ppNode,prev);197 }198 }199
200 /*
201 //版本2:指针的引用202 private:203 //对于待插入的节点,选择合适的位置插入204 void _list_insert_sort(ListNode*& ppNode, ListNode *pNode)205 {206 ListNode* prev = NULL;207 ListNode* cur = NULL;208
209 if(pNode->val < ppNode->val)210 {211 pNode->next = ppNode;212 ppNode = pNode;213 return;214 }215
216 cur = ppNode;217
218 while(cur != NULL)219 {220 if(pNode->val < cur->val)221 break;222
223 prev = cur;224 cur = cur->next;225 }226
227 pNode->next = cur;//或pNode->next = prev->next228 prev->next =pNode;229 return;230 }231 public:232 //首先遍历节点,一边是排序好的节点,一边是待排序的节点233 void list_insert_sort(ListNode*& ppNode)234 {235 ListNode* prev = NULL;236 ListNode* cur = NULL;237
238 if(NULL == ppNode)239 return;240
241 cur = ppNode->next;242 ppNode->next = NULL;243
244 while(cur != NULL)245 {246 prev = cur;247 cur = cur->next;248 _list_insert_sort(ppNode,prev);249 }250 }251 */
252
253 };254
255
256 //链表归并排序
257 template
258 classList_merge_sort259 {260 private:261 //合并两端链表262 //因为可能在头结点之前插入数据,故为ListNode** list1
263 ListNode* list_merge(ListNode* list1, ListNode*list2)264 {265 if(NULL ==list1)266 returnlist2;267 else if(NULL ==list2)268 returnlist1;269
270 ListNode* dummy = new ListNode(-1);//辅助头结点
271 dummy->next =list1;272 ListNode* list1_cur =dummy;273 ListNode* list2_cur =list2;274
275 while(list1_cur->next != NULL && list2_cur !=NULL)276 {277 //cout<< list1_cur->next->val <val<
279 if(list1_cur->next->val > list2_cur->val)//注意:不可以是大于等于,那样就不稳定了
280 {281 list2 = list2->next;282 list2_cur->next = list1_cur->next;283 list1_cur->next =list2_cur;284 list1_cur =list2_cur;285 list2_cur =list2;286 }287 else//后面一段list2的元素大于等于前面一段list1的元素时,前面一段指针直接后移
288 list1_cur = list1_cur->next;289 }290 //后面一段list2中可能还有元素或NULL,总之把它接到list1后面
291 if(NULL == list1_cur->next)292 list1_cur->next =list2_cur;293
294 ListNode* pHead = dummy->next;295 delete dummy;//释放dummy
296 return pHead;//返回头结点
297 }298
299 //归并排序辅助函数(因为可能在头结点之前插入数据,故为ListNode** pHead)
300 ListNode* _list_merge_sort(ListNode**pHead)301 {302 if(NULL == *pHead || NULL == (*pHead)->next)303 return *pHead;304
305 ListNode* pSlow = *pHead;306 ListNode* pFast = *pHead;307 while(pFast->next !=NULL && pFast->next->next !=NULL)308 {309 pSlow = pSlow->next;310 pFast = pFast->next->next;311 }312
313 ListNode* pLeftHead = *pHead;314 ListNode* pRightHead = pSlow->next;315 pSlow->next = NULL;//左半链表尾节点的next赋空值
316
317 /*pLeftHead =*/_list_merge_sort(&pLeftHead);318 /*pRightHead =*/_list_merge_sort(&pRightHead);319
320 //注意:虽然传值,但是内部状态可变,因此pLeftHead和pRightHead内部321 //的的next可能已经变了,因此他们可能伸长或缩短
322 *pHead = list_merge(pLeftHead,pRightHead);//修改头指针
323 return *pHead;324 }325 public:326 //归并排序入口,去掉了返回值,不包装这一层也行
327 void list_merge_sort(ListNode**pHead)328 {329 _list_merge_sort(pHead);//注意这里传入的是地址
330 }331 };332
333 //链表快速排序(测试样例)
334 voidtest_list_qsort()335 {336 //创建结点
337 ListNode* pNode1 = create_list_node(1.8);338 ListNode* pNode2 = create_list_node(7.3);339 ListNode* pNode3 = create_list_node(2.6);340 ListNode* pNode4 = create_list_node(6);341 ListNode* pNode5 = create_list_node(-5.8);342 ListNode* pNode6 = create_list_node(99.5);343 ListNode* pNode7 = create_list_node(13);344 ListNode* pNode8 = create_list_node(45);345 ListNode* pNode9 = create_list_node(-7);346
347 //连接结点
348 connect_list_node(pNode1,pNode2);349 connect_list_node(pNode2,pNode3);350 connect_list_node(pNode3,pNode4);351 connect_list_node(pNode4,pNode5);352 connect_list_node(pNode5,pNode6);353 connect_list_node(pNode6,pNode7);354 connect_list_node(pNode7,pNode8);355 connect_list_node(pNode8,pNode9);356
357 //打印链表
358 cout<
360 //快速排序
361 List_qsorttest_qsort;362 test_qsort.list_qsort(pNode1);//传值363 //test_qsort.list_qsort(&pNode1);//传指针364 //test_qsort.list_qsort(pNode1);//传引用
365
366 cout<
368 /**********销毁链表(我们一般用到的方法,会出现空悬指针)********************/
369 //destory_list(&pNode1);370 // //注意,释放链表后,头结点为NULL,其余的虽然释放了,但地址还在,因此成为空悬指针,需要进一步释放371 // //从这个角度来看,还不如写个函数释放每个节点,因此写了一个372
373
374 //if(pNode1)375 //print_list(pNode1);376 //else377 //cout<
378 /***********************************************************************/
379
380 /****************销毁链表(逐个销毁,不会出现空悬指针)*********************/
381 destory_Node(&pNode1);382 destory_Node(&pNode2);383 destory_Node(&pNode3);384 destory_Node(&pNode4);385 destory_Node(&pNode5);386 destory_Node(&pNode6);387 destory_Node(&pNode7);388 destory_Node(&pNode8);389 destory_Node(&pNode9);390 //if(pNode1)391 //print_list(pNode1);392 //else393 //cout<
394 /***********************************************************************/
395
396 }397
398 //链表插入排序(测试样例)
399 voidtest_list_insertion_sort()400 {401 //创建结点
402 ListNode* pNode1 = create_list_node(1.8);403 ListNode* pNode2 = create_list_node(7.3);404 ListNode* pNode3 = create_list_node(2.6);405 ListNode* pNode4 = create_list_node(6);406 ListNode* pNode5 = create_list_node(-5.8);407 ListNode* pNode6 = create_list_node(99.5);408 ListNode* pNode7 = create_list_node(13);409 ListNode* pNode8 = create_list_node(45);410 ListNode* pNode9 = create_list_node(-7);411
412 //连接结点
413 connect_list_node(pNode1,pNode2);414 connect_list_node(pNode2,pNode3);415 connect_list_node(pNode3,pNode4);416 connect_list_node(pNode4,pNode5);417 connect_list_node(pNode5,pNode6);418 connect_list_node(pNode6,pNode7);419 connect_list_node(pNode7,pNode8);420 connect_list_node(pNode8,pNode9);421
422 //打印链表
423 cout<
425 //插入排序
426 List_insertion_sorttest_insertion_sort;427 test_insertion_sort.list_insert_sort(&pNode1);//传指针428 //test_insertion_sort.list_insert_sort(pNode1);//传引用
429
430 cout<
433 //链表归并排序(测试样例)
434 voidtest_list_merge_sort()435 {436 //创建结点
437 ListNode* pNode1 = create_list_node(1.8);438 ListNode* pNode2 = create_list_node(7.3);439 ListNode* pNode3 = create_list_node(2.6);440 ListNode* pNode4 = create_list_node(6);441 ListNode* pNode5 = create_list_node(-5.8);442 ListNode* pNode6 = create_list_node(99.5);443 ListNode* pNode7 = create_list_node(13);444 ListNode* pNode8 = create_list_node(45);445 ListNode* pNode9 = create_list_node(-7);446
447 //连接结点
448 connect_list_node(pNode1,pNode2);449 connect_list_node(pNode2,pNode3);450 connect_list_node(pNode3,pNode4);451 connect_list_node(pNode4,pNode5);452 connect_list_node(pNode5,pNode6);453 connect_list_node(pNode6,pNode7);454 connect_list_node(pNode7,pNode8);455 connect_list_node(pNode8,pNode9);456
457 //打印链表
458 cout<
460 //归并排序
461 List_merge_sorttest_merge_sort;462 //ListNode* p=test_merge_sort.list_merge_sort(&pNode1);//传指针
463 test_merge_sort.list_merge_sort(&pNode1);464
465 cout<
468
469 intmain()470 {471 cout<