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