c语言链表qsort排序,【模板小程序】链表排序(qsort/insert_sort/merge_sort)-站长资讯中心...

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<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值