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

Posted lyrich

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了写给自己看的单链表:归并排序相关的知识,希望对你有一定的参考价值。

搬运自我的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 }

 

以上是关于写给自己看的单链表:归并排序的主要内容,如果未能解决你的问题,请参考以下文章

单链表

精益求精单链表归并排序与快速排序

归并排序

归并排序

Java实现单链表的快速排序和归并排序

java 单链表的归并排序