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

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

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

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

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

要解决的是两个问题,一是如何分段,二是如何合并左段和右段。合并左段和右段可以用写给自己看的单链表(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

代码如下:

void MergeSort(Lnode *head)
{
	if (head->next == NULL)
		return;
	head->next = MergeSortCore(head->next);
}

Lnode *MergeSortCore(Lnode *head)
{
	if (head->next == NULL)
		return head;

	Lnode *slow, *fast;
	slow = head;
	fast = slow->next;
	while (fast != NULL) {
		fast = fast->next;
		if (fast != NULL) { 
			slow = slow->next;
			fast = fast->next;
		}
	}

	Lnode *righthead;
	righthead = slow->next;
	slow->next = NULL;
	head = MergeSortCore(head);
	righthead = MergeSortCore(righthead);
	return MergeListCore(head, righthead);
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值