码迷,mamicode.com
首页 > 编程语言 > 详细

写给自己看的单链表(5):归并排序

时间:2019-03-24 09:51:29      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:递归   不包含   一个   csdn   http   class   参考   .net   hang   

搬运自我的CSDN https://blog.csdn.net/u013213111/article/details/88670270

!!!Attention:以下操作中的单链表均带有头结点!!!
参考怎样实现链表的归并排序

由于待处理的单链表带有头结点,因此把程序分为MergeSort和MergeSortCore两部分,其中MergeSort只是用来处理头结点的,这与写给自己看的单链表(2):进阶操作中的合并程序类似。

从MergeSortCore的伪代码可以一窥归并排序的思路:

1 Lnode *MergeSortCore(Lnode *head)
2 {
3     if 元素只有一个(已经有序)return;
4         划分为左右两段
5     对左段进行MergeSortCore
6     对右段进行MergeSortCore
7     //此时左段和右端已经有序
8     对左段和右段进行合并(MergeListCore)
9 }

要解决的是两个问题,一是如何分段,二是如何合并左段和右段。合并左段和右段可以用写给自己看的单链表(2):进阶操作中已经写好的MergeListCore,那么剩下的问题就是如何分段了。

分段用的是追及的思路:

使用一个slow指针和一个fast指针,让fast指针相对slow指针的移动速度是单位1。这样fast走到尽头时,slow就在“中间”位置了。

这样可以把链表分为两段:[left, slow->next) 和 [right, fast),这里的left和right均不包含头结点。right即为slow->next,在对right进行了赋值后,要注意把slow->next赋值为NULL,否则在递归MergeListCore时找不到终止点。fast其实就是NULL,所以分段的循环条件为fast != NULL。

代码如下:

 1 void MergeSort(Lnode *head)
 2 {
 3     if (head->next == NULL)
 4         return;
 5     head->next = MergeSortCore(head->next);
 6 }
 7 
 8 Lnode *MergeSortCore(Lnode *head)
 9 {
10     if (head->next == NULL)
11         return head;
12 
13     Lnode *slow, *fast;
14     slow = head;
15     fast = slow->next;
16     while (fast != NULL) {
17         fast = fast->next;
18         if (fast != NULL) { 
19             slow = slow->next;
20             fast = fast->next;
21         }
22     }
23 
24     Lnode *righthead;
25     righthead = slow->next;
26     slow->next = NULL;
27     head = MergeSortCore(head);
28     righthead = MergeSortCore(righthead);
29     return MergeListCore(head, righthead);
30 }

 

写给自己看的单链表(5):归并排序

标签:递归   不包含   一个   csdn   http   class   参考   .net   hang   

原文地址:https://www.cnblogs.com/lyrich/p/10586633.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!