前言

本文章整理了链表排序的三种方法,分别是快速排序、插入排序、归并排序。为适应不同用途,先给出常用的int版本,再在此基础上抽象出类模板。

目录

一、针对整数的版本(常用)

  1. 文中链表定义
  2. 链表相关操作
  3. 三种排序方法
  4. 完整测试程序

二、模板版本(适用性广泛)

  1. 文中链表定义
  2. 链表相关操作
  3. 三种排序方法
  4. 完整测试程序

总结

参考文章

一、针对整数的版本(常用)

文中链表定义:

  1. //definition for singly-linked list.
  2. struct ListNode
  3. {
  4. int val;
  5. ListNode* next;
  6. ListNode(int x) : val(x), next(NULL) {}
  7. };

链表相关操作:

  1. //链表结点构造
  2. ListNode* create_list_node(int val)
  3. {
  4. ListNode* pNode = new ListNode(val);
  5. return pNode;
  6. }
  7. //链表结点连接
  8. void connect_list_node(ListNode* pCur, ListNode* pNext)
  9. {
  10. pCur->next = pNext;
  11. }
  12.  
  13. //销毁单个节点(其实用这个更好,不会出现空悬指针)
  14. void destory_Node(ListNode** ppNode)
  15. {
  16. if(*ppNode != NULL)
  17. delete *ppNode;
  18. *ppNode = NULL;
  19. }
  20.  
  21. //链表销毁(注意,除头节点外,其他节点均变成了空悬指针,不建议此用法)
  22. void destory_list(ListNode** ppHead)
  23. {
  24. ListNode** cur = ppHead;
  25. while(*cur != NULL)
  26. {
  27. ListNode* tmp = (*cur)->next;//保存下一个节点
  28. delete *cur;
  29. *cur = NULL;
  30. *cur = tmp;
  31. }
  32. }
  33.  
  34. //链表打印(不支持有环的链表;如果链表有环,需判断环入口等等另外处理)
  35. void print_list(ListNode* pHead)
  36. {
  37. ListNode* cur = pHead;
  38. while(cur != NULL)
  39. {
  40. cout<< cur->val <<" ";
  41. cur = cur->next;
  42. }
  43. cout<<endl;
  44. }

三种排序方法:

  1. //链表快速排序
  2. class List_qsort
  3. {
  4. private:
  5. //交换元素
  6. void list_swap(int& lhs,int& rhs)
  7. {
  8. int tmp = lhs;
  9. lhs = rhs;
  10. rhs = tmp;
  11. }
  12. //划分,使左边小于头结点元素,右边大于等于头结点元素
  13. ListNode* list_partion(ListNode* pBegin,ListNode* pEnd)
  14. {
  15. if(pBegin == pEnd || pBegin->next == NULL)
  16. return pBegin;
  17.  
  18. ListNode* pSlow=pBegin;
  19. ListNode* pFast=pBegin;
  20. int key=pBegin->val;
  21. while(pFast != pEnd)
  22. {
  23.  
  24. if(pFast->val < key)
  25. {
  26. pSlow = pSlow->next;
  27. list_swap(pSlow->val,pFast->val);
  28. }
  29. pFast = pFast->next;
  30. }
  31.  
  32. list_swap(pSlow->val,pBegin->val);
  33.  
  34. return pSlow;
  35. }
  36. //排序辅助函数
  37. void _list_qsort(ListNode* pBegin,ListNode* pEnd)
  38. {
  39. if(pBegin == pEnd || NULL == pBegin->next)
  40. return;
  41. ListNode* mid=list_partion(pBegin,pEnd);
  42. _list_qsort(pBegin,mid);
  43. _list_qsort(mid->next,pEnd);
  44. }
  45. public:
  46. //排序入口函数(版本1:传值)
  47. void list_qsort(ListNode* pHead)
  48. {
  49. if(pHead == NULL || pHead->next ==NULL)
  50. return ;
  51. _list_qsort(pHead,NULL);
  52.  
  53. }
  54.  
  55. /*
  56. //排序入口函数(版本2:传指针)
  57. void list_qsort(ListNode** ppHead)
  58. {
  59. if(*ppHead == NULL || (*ppHead)->next ==NULL)
  60. return;
  61. _list_qsort(*ppHead,NULL);
  62. }
  63. */
  64.  
  65. /*
  66. //排序入口函数(版本3:传引用)
  67. void list_qsort(ListNode*& pHead)
  68. {
  69. if(NULL == pHead || NULL == pHead->next )
  70. return;
  71. _list_qsort(pHead,NULL);
  72. }
  73. */
  74. };
  1. //链表插入排序
  2. class List_insertion_sort
  3. {
  4.  
  5. //版本1:指针的指针
  6. private:
  7. //对于待插入的节点,选择合适的位置插入
  8. void _list_insert_sort(ListNode** ppNode, ListNode *pNode)
  9. {
  10. ListNode* prev = NULL;
  11. ListNode* cur = NULL;
  12.  
  13. if(pNode->val < (*ppNode)->val)
  14. {
  15. pNode->next = *ppNode;
  16. (*ppNode) = pNode;
  17. return;
  18. }
  19.  
  20. cur = *ppNode;
  21.  
  22. while(cur != NULL)
  23. {
  24. if(pNode->val < cur->val)
  25. break;
  26.  
  27. prev = cur;
  28. cur = cur->next;
  29. }
  30.  
  31. pNode->next = cur;//或pNode->next = prev->next
  32. prev->next =pNode;
  33. return;
  34. }
  35. public:
  36. //首先遍历节点,一边是排序好的节点,一边是待排序的节点
  37. void list_insert_sort(ListNode** ppNode)
  38. {
  39. ListNode* prev = NULL;
  40. ListNode* cur = NULL;
  41.  
  42. if(NULL == ppNode || NULL == *ppNode)
  43. return;
  44.  
  45. cur = (*ppNode)->next;
  46. (*ppNode)->next = NULL;
  47.  
  48. while(cur != NULL)
  49. {
  50. prev = cur;
  51. cur = cur->next;
  52. _list_insert_sort(ppNode,prev);
  53. }
  54. }
  55.  
  56. /*
  57. //版本2:指针的引用
  58. private:
  59. //对于待插入的节点,选择合适的位置插入
  60. void _list_insert_sort(ListNode*& ppNode, ListNode *pNode)
  61. {
  62. ListNode* prev = NULL;
  63. ListNode* cur = NULL;
  64.  
  65. if(pNode->val < ppNode->val)
  66. {
  67. pNode->next = ppNode;
  68. ppNode = pNode;
  69. return;
  70. }
  71.  
  72. cur = ppNode;
  73.  
  74. while(cur != NULL)
  75. {
  76. if(pNode->val < cur->val)
  77. break;
  78.  
  79. prev = cur;
  80. cur = cur->next;
  81. }
  82.  
  83. pNode->next = cur;//或pNode->next = prev->next
  84. prev->next =pNode;
  85. return;
  86. }
  87. public:
  88. //首先遍历节点,一边是排序好的节点,一边是待排序的节点
  89. void list_insert_sort(ListNode*& ppNode)
  90. {
  91. ListNode* prev = NULL;
  92. ListNode* cur = NULL;
  93.  
  94. if(NULL == ppNode)
  95. return;
  96.  
  97. cur = ppNode->next;
  98. ppNode->next = NULL;
  99.  
  100. while(cur != NULL)
  101. {
  102. prev = cur;
  103. cur = cur->next;
  104. _list_insert_sort(ppNode,prev);
  105. }
  106. }
  107. */
  108.  
  109. };
  1. //链表归并排序
  2. class List_merge_sort
  3. {
  4. private:
  5. //合并两端链表
  6. //因为可能在头结点之前插入数据,故为ListNode** list1
  7. ListNode* list_merge(ListNode* list1, ListNode* list2)
  8. {
  9. if(NULL == list1)
  10. return list2;
  11. else if(NULL == list2)
  12. return list1;
  13.  
  14. ListNode* dummy = new ListNode(-);//辅助头结点
  15. dummy->next = list1;
  16. ListNode* list1_cur = dummy;
  17. ListNode* list2_cur = list2;
  18.  
  19. while(list1_cur->next != NULL && list2_cur != NULL)
  20. {
  21. //cout<< list1_cur->next->val <<"==="<< list2_cur->val<<endl;
  22. //把后面一段list2更小的元素插入前面一段list1中
  23. if(list1_cur->next->val > list2_cur->val)//注意:不可以是大于等于,那样就不稳定了
  24. {
  25. list2 = list2->next;
  26. list2_cur->next = list1_cur->next;
  27. list1_cur->next = list2_cur;
  28. list1_cur = list2_cur;
  29. list2_cur = list2;
  30. }
  31. else//后面一段list2的元素大于等于前面一段list1的元素时,前面一段指针直接后移
  32. list1_cur = list1_cur->next;
  33. }
  34. //后面一段list2中可能还有元素或NULL,总之把它接到list1后面
  35. if(NULL == list1_cur->next)
  36. list1_cur->next = list2_cur;
  37.  
  38. ListNode* pHead = dummy->next;
  39. delete dummy;//释放dummy
  40. return pHead;//返回头结点
  41. }
  42.  
  43. //归并排序辅助函数(因为可能在头结点之前插入数据,故为ListNode** pHead)
  44. ListNode* _list_merge_sort(ListNode** pHead)
  45. {
  46. if(NULL == *pHead || NULL == (*pHead)->next)
  47. return *pHead;
  48.  
  49. ListNode* pSlow = *pHead;
  50. ListNode* pFast = *pHead;
  51. while(pFast->next !=NULL && pFast->next->next !=NULL)
  52. {
  53. pSlow = pSlow->next;
  54. pFast = pFast->next->next;
  55. }
  56.  
  57. ListNode* pLeftHead = *pHead;
  58. ListNode* pRightHead = pSlow->next;
  59. pSlow->next = NULL;//左半链表尾节点的next赋空值
  60.  
  61. /*pLeftHead = */_list_merge_sort(&pLeftHead);
  62. /*pRightHead = */_list_merge_sort(&pRightHead);
  63.  
  64. //注意:虽然传值,但是内部状态可变,因此pLeftHead和pRightHead内部
  65. //的的next可能已经变了,因此他们可能伸长或缩短
  66. *pHead = list_merge(pLeftHead,pRightHead);//修改头指针
  67. return *pHead;
  68. }
  69. public:
  70. //归并排序入口,去掉了返回值,不包装这一层也行
  71. void list_merge_sort(ListNode** pHead)
  72. {
  73. _list_merge_sort(pHead);//注意这里传入的是地址
  74. }
  75. };

完整测试程序:

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

二、模板版本(适用性广泛)

文中链表定义:

  1. //definition for singly-linked list.
  2. template <typename T>
  3. struct ListNode
  4. {
  5. T val;
  6. ListNode<T>* next;
  7. ListNode(T x) : val(x), next(NULL) {}
  8. };

链表相关操作:

  1. //链表结点构造
  2. template <typename T>
  3. ListNode<T>* create_list_node(T val)
  4. {
  5. ListNode<T>* pNode = new ListNode<T>(val);
  6. return pNode;
  7. }
  8.  
  9. //链表结点连接
  10. template <typename T>
  11. void connect_list_node(ListNode<T>* pCur, ListNode<T>* pNext)
  12. {
  13. pCur->next = pNext;
  14. }
  15.  
  16. //销毁单个节点(其实用这个更好,不会出现空悬指针)
  17. template <typename T>
  18. void destory_Node(ListNode<T>** ppNode)
  19. {
  20. if(*ppNode != NULL)
  21. delete *ppNode;
  22. *ppNode = NULL;
  23. }
  24.  
  25. //链表销毁(注意,除头节点外,其他节点均变成了空悬指针,不建议此种方法)
  26. template <typename T>
  27. void destory_list(ListNode<T>** ppHead)
  28. {
  29. ListNode<T>** cur = ppHead;
  30. while(*cur != NULL)
  31. {
  32. ListNode<T>* tmp = (*cur)->next;//保存下一个节点
  33. delete *cur;
  34. *cur = NULL;
  35. *cur = tmp;
  36. }
  37. }
  38.  
  39. //链表打印
  40. template <typename T>
  41. void print_list(ListNode<T>* pHead)
  42. {
  43. ListNode<T>* cur = pHead;
  44. while(cur != NULL)
  45. {
  46. cout<< cur->val <<" ";
  47. cur = cur->next;
  48. }
  49. cout<<endl;
  50. }

三种排序方法:

  1. //链表快速排序
  2. template <typename T>
  3. class List_qsort
  4. {
  5. private:
  6. //划分,使左边小于头结点元素,右边大于等于头结点元素
  7. ListNode<T>* list_partion(ListNode<T>* pBegin,ListNode<T>* pEnd)
  8. {
  9. if(pBegin == pEnd || pBegin->next == NULL)
  10. return pBegin;
  11.  
  12. ListNode<T>* pSlow=pBegin;
  13. ListNode<T>* pFast=pBegin;
  14. ListNode<T>* pKey=new ListNode<T>(pBegin->val);//只为了保存用于比较的val
  15. while(pFast != pEnd)
  16. {
  17.  
  18. if(pFast->val < pKey->val)
  19. {
  20. pSlow = pSlow->next;
  21. swap(pSlow->val,pFast->val);
  22. }
  23. pFast = pFast->next;
  24. }
  25.  
  26. swap(pSlow->val,pBegin->val);
  27. delete pKey;//释放pKey
  28. return pSlow;
  29. }
  30. //排序辅助函数
  31. void _list_qsort(ListNode<T>* pBegin,ListNode<T>* pEnd)
  32. {
  33. if(pBegin == pEnd || NULL == pBegin->next)
  34. return;
  35. ListNode<T>* mid=list_partion(pBegin,pEnd);
  36. _list_qsort(pBegin,mid);
  37. _list_qsort(mid->next,pEnd);
  38. }
  39. public:
  40. //排序入口函数(版本1:传值)
  41. void list_qsort(ListNode<T>* pHead)
  42. {
  43. if(pHead == NULL || pHead->next ==NULL)
  44. return ;
  45. _list_qsort(pHead,NULL);
  46.  
  47. }
  48.  
  49. /*
  50. //排序入口函数(版本2:传指针)
  51. void list_qsort(ListNode<T>** ppHead)
  52. {
  53. if(*ppHead == NULL || (*ppHead)->next ==NULL)
  54. return;
  55. _list_qsort(*ppHead,NULL);
  56. }
  57. */
  58.  
  59. /*
  60. //排序入口函数(版本3:传引用)
  61. void list_qsort(ListNode<T>*& pHead)
  62. {
  63. if(NULL == pHead || NULL == pHead->next )
  64. return;
  65. _list_qsort(pHead,NULL);
  66. }
  67. */
  68. };
  1. //链表插入排序
  2. template <typename T>
  3. class List_insertion_sort
  4. {
  5.  
  6. //版本1:指针的指针
  7. private:
  8. //对于待插入的节点,选择合适的位置插入
  9. void _list_insert_sort(ListNode<T>** ppNode, ListNode<T>* pNode)
  10. {
  11. ListNode<T>* prev = NULL;
  12. ListNode<T>* cur = NULL;
  13.  
  14. if(pNode->val < (*ppNode)->val)
  15. {
  16. pNode->next = *ppNode;
  17. (*ppNode) = pNode;
  18. return;
  19. }
  20.  
  21. cur = *ppNode;
  22.  
  23. while(cur != NULL)
  24. {
  25. if(pNode->val < cur->val)
  26. break;
  27.  
  28. prev = cur;
  29. cur = cur->next;
  30. }
  31.  
  32. pNode->next = cur;//或pNode->next = prev->next
  33. prev->next =pNode;
  34. return;
  35. }
  36. public:
  37. //首先遍历节点,一边是排序好的节点,一边是待排序的节点
  38. void list_insert_sort(ListNode<T>** ppNode)
  39. {
  40. ListNode<T>* prev = NULL;
  41. ListNode<T>* cur = NULL;
  42.  
  43. if(NULL == ppNode || NULL == *ppNode)
  44. return;
  45.  
  46. cur = (*ppNode)->next;
  47. (*ppNode)->next = NULL;
  48.  
  49. while(cur != NULL)
  50. {
  51. prev = cur;
  52. cur = cur->next;
  53. _list_insert_sort(ppNode,prev);
  54. }
  55. }
  56.  
  57. /*
  58. //版本2:指针的引用
  59. private:
  60. //对于待插入的节点,选择合适的位置插入
  61. void _list_insert_sort(ListNode<T>*& ppNode, ListNode<T> *pNode)
  62. {
  63. ListNode<T>* prev = NULL;
  64. ListNode<T>* cur = NULL;
  65.  
  66. if(pNode->val < ppNode->val)
  67. {
  68. pNode->next = ppNode;
  69. ppNode = pNode;
  70. return;
  71. }
  72.  
  73. cur = ppNode;
  74.  
  75. while(cur != NULL)
  76. {
  77. if(pNode->val < cur->val)
  78. break;
  79.  
  80. prev = cur;
  81. cur = cur->next;
  82. }
  83.  
  84. pNode->next = cur;//或pNode->next = prev->next
  85. prev->next =pNode;
  86. return;
  87. }
  88. public:
  89. //首先遍历节点,一边是排序好的节点,一边是待排序的节点
  90. void list_insert_sort(ListNode<T>*& ppNode)
  91. {
  92. ListNode<T>* prev = NULL;
  93. ListNode<T>* cur = NULL;
  94.  
  95. if(NULL == ppNode)
  96. return;
  97.  
  98. cur = ppNode->next;
  99. ppNode->next = NULL;
  100.  
  101. while(cur != NULL)
  102. {
  103. prev = cur;
  104. cur = cur->next;
  105. _list_insert_sort(ppNode,prev);
  106. }
  107. }
  108. */
  109.  
  110. };
  1. //链表归并排序
  2. template <typename T>
  3. class List_merge_sort
  4. {
  5. private:
  6. //合并两端链表
  7. //因为可能在头结点之前插入数据,故为ListNode<T>** list1
  8. ListNode<T>* list_merge(ListNode<T>* list1, ListNode<T>* list2)
  9. {
  10. if(NULL == list1)
  11. return list2;
  12. else if(NULL == list2)
  13. return list1;
  14.  
  15. ListNode<T>* dummy = new ListNode<T>(-);//辅助头结点
  16. dummy->next = list1;
  17. ListNode<T>* list1_cur = dummy;
  18. ListNode<T>* list2_cur = list2;
  19.  
  20. while(list1_cur->next != NULL && list2_cur != NULL)
  21. {
  22. //cout<< list1_cur->next->val <<"==="<< list2_cur->val<<endl;
  23. //把后面一段list2更小的元素插入前面一段list1中
  24. if(list1_cur->next->val > list2_cur->val)//注意:不可以是大于等于,那样就不稳定了
  25. {
  26. list2 = list2->next;
  27. list2_cur->next = list1_cur->next;
  28. list1_cur->next = list2_cur;
  29. list1_cur = list2_cur;
  30. list2_cur = list2;
  31. }
  32. else//后面一段list2的元素大于等于前面一段list1的元素时,前面一段指针直接后移
  33. list1_cur = list1_cur->next;
  34. }
  35. //后面一段list2中可能还有元素或NULL,总之把它接到list1后面
  36. if(NULL == list1_cur->next)
  37. list1_cur->next = list2_cur;
  38.  
  39. ListNode<T>* pHead = dummy->next;
  40. delete dummy;//释放dummy
  41. return pHead;//返回头结点
  42. }
  43.  
  44. //归并排序辅助函数(因为可能在头结点之前插入数据,故为ListNode<T>** pHead)
  45. ListNode<T>* _list_merge_sort(ListNode<T>** pHead)
  46. {
  47. if(NULL == *pHead || NULL == (*pHead)->next)
  48. return *pHead;
  49.  
  50. ListNode<T>* pSlow = *pHead;
  51. ListNode<T>* pFast = *pHead;
  52. while(pFast->next !=NULL && pFast->next->next !=NULL)
  53. {
  54. pSlow = pSlow->next;
  55. pFast = pFast->next->next;
  56. }
  57.  
  58. ListNode<T>* pLeftHead = *pHead;
  59. ListNode<T>* pRightHead = pSlow->next;
  60. pSlow->next = NULL;//左半链表尾节点的next赋空值
  61.  
  62. /*pLeftHead = */_list_merge_sort(&pLeftHead);
  63. /*pRightHead = */_list_merge_sort(&pRightHead);
  64.  
  65. //注意:虽然传值,但是内部状态可变,因此pLeftHead和pRightHead内部
  66. //的的next可能已经变了,因此他们可能伸长或缩短
  67. *pHead = list_merge(pLeftHead,pRightHead);//修改头指针
  68. return *pHead;
  69. }
  70. public:
  71. //归并排序入口,去掉了返回值,不包装这一层也行
  72. void list_merge_sort(ListNode<T>** pHead)
  73. {
  74. _list_merge_sort(pHead);//注意这里传入的是地址
  75. }
  76. };

完整测试程序:

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

总结

链表的操作都基于指针,我们可以通过编写其各种排序代码练习对指针的操作,如指针的指针,指针的引用等。

另外,我这里只是演示了三种排序方法,如果有错误敬请指正。大家可试试编写几种其他的排序方法。

参考文章

在此对以上文章作者表示感谢。欢迎交流。

【模板小程序】链表排序(qsort/insert_sort/merge_sort)的更多相关文章

  1. 模板小程序】求小于等于N范围内的质数

    xiaoxi666 联系邮箱: xiaoxi666swap@163.com 博客园 首页 新随笔 联系 订阅 管理 [模板小程序]求小于等于N范围内的质数   1 //筛法求N以内的素数(普通法+优化 ...

  2. 【模板小程序】求小于等于N范围内的质数

    //筛法求N以内的素数(普通法+优化),N>=2 #include <iostream> #include <cmath> #include <vector> ...

  3. 【模板小程序】求M~N范围内的质数个数

    /* 本程序说明: [编程题] 求素数 时间限制:2秒 空间限制:32768K 输入M.N,1 < M < N < 1000000,求区间[M,N]内的所有素数的个数.素数定义:除了 ...

  4. 【模板小程序】循环方阵构造(仿《剑指offer》循环矩阵打印)

    /* 本程序说明: 输入:方阵大小n,输出:n*n的旋转方阵 举例: 当n=2时,输出: 1 2 4 3 当n=4时,输出: 1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 ...

  5. 【模板小程序】求第n个fibonacci数

    //fibonacci,find the nth num. 1 1 2 3 5 8... #include <iostream> using namespace std; int fib( ...

  6. 【模板小程序】求第n个质数

    #include <iostream> #include <vector> using namespace std; int nth_prime(int n) { vector ...

  7. 【模板小程序】任意长度非负十进制数转化为二进制(java实现)

    妈妈再也不用担心十进制数过大了233(注意只支持非负数) import com.google.common.base.Strings; import java.math.BigInteger; imp ...

  8. 微信小程序学习指南

    作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  9. “我的小程序”来了 新版微信v6.7.1下拉就能找到

    今天iOS版微信迎来v6.7.1正式版发布,本次升级主要是可以把常用的小程序添加到“我的小程序”.近期版本微信可以直接浏览订阅号的消息,扫一扫可拍照翻译整页中英文,浏览的文章支持缩小为浮窗.两大更新如 ...

随机推荐

  1. JavaScript事件与例子

    事件,就是预先设置好的一段代码,等到用户触发的时候执行. 一:常见的事件: 1.关于鼠标的事件 onclick 鼠标单击触发 ondblclick 鼠标双击触发 onmouseover 鼠标移上触发 ...

  2. 【知识整理】这可能是最好的RxJava 2.x 入门教程(二)

    这可能是最好的RxJava 2.x入门教程系列专栏 文章链接: 这可能是最好的RxJava 2.x 入门教程(一) GitHub 代码同步更新:https://github.com/nanchen22 ...

  3. 【Android Developers Training】 6. 配置Action Bar

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  4. Angular 4 学习笔记 从入门到实战 打造在线竞拍网站 基础知识 快速入门 个人感悟

    最近搞到手了一部Angular4的视频教程,这几天正好有时间变学了一下,可以用来做一些前后端分离的网站,也可以直接去打包web app. 环境&版本信息声明 运行ng -v @angular/ ...

  5. Vijos 1012 清帝之惑之雍正 平面最近点对(分治)

    背景 雍正帝胤祯,生于康熙十七年(1678)是康熙的第四子.康熙61年,45岁的胤祯继承帝位,在位13年,死于圆明园.庙号世宗. 胤祯是在康乾盛世前期--康熙末年社会出现停滞的形式下登上历史舞台的.复 ...

  6. VB6之断点续传

    闲来无事,研究了下HTTP的断点续传,用VB6写了小Demo. 关于HTTP-Range细节可参考: http://www.w3.org/Protocols/rfc2616/rfc2616.html ...

  7. Struts2的知识点小总结

    strust2是 struts1和webwork的结合  (本质相当于servlet) 核心:拦截器 interceptor  action ognl和valuestack 使用struts的准备工作 ...

  8. java constructor 在构造子类时,一定会调用到父类的构造方法 “ 私有属性被继承了?”问题

    ” Error:Implicit super constructor Pet() is undefined. Must explicitly invoke another constructor “ ...

  9. JavaScript+svg绘制的一个动态时钟

    结果图: 代码如下: <!DOCTYPE html> <html> <head> <title>动态时钟</title> </head ...

  10. RecyclerView-------之GridView模式加载更多

    随着RecyclerView的出现,Listview.GridView的使用率相对有些减少,废话不多说,先看一下效果: 代码如下: 1.自定义的RecyclerView(根据自己的需要) public ...