Leetcode :Sort List

本文介绍了一种使用归并排序思想实现链表排序的方法,通过逐步增加步长的方式完成整个链表的排序过程,时间复杂度为O(nlogn),空间复杂度为O(1)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 代码写的有点烂,希望能表达自己的意思。欢迎各位提意见~~微笑

/*
author:JTR@BNU
思路:使用归并排序的思想,使用逐步增加步长的方法将整个链表的排序逐步从最简单的长度为1的两个链表归并,直到最终长度达到链表长度
*/
/*
Sort a linked list in O(n log n) time using constant space complexity.
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
	ListNode *sortList(ListNode *head) {
		if (head == NULL || head->next == NULL)
		{
			return head;
		}
		int step = 1, length = 0; //step是控制归并排序每次增长的步长,length是所给链表的长度
		ListNode * firstList, *secondList;//f分别指向两个需要归并排序的链表头
		//下面是计算链表长度
		firstList = head;
		while (firstList)
		{
			length++;
			firstList = firstList->next;
		}
		
		//整个控制步长增长的循环
		while (length - step > 0)
		{
			ListNode * ne = head; //记录下次第一个链表开始的地方,初始是整个链表的头
			ListNode * lastHead = new ListNode(0);//用于指向每次归并排序得到的排好序的头,是一个临时节点,最终应该Del
			ListNode * newHead = lastHead; //记录每次归并排序最后一个节点,为了和下一个归并排序之后的链表结合
			while (ne)//一直到整个链表的最后
			{
				firstList = ne;
				secondList = firstList;
				int tem = step, len1 = 0, len2 = 0;
				while (tem && secondList->next != NULL)
				{
					secondList = secondList->next;
					tem--;
				}
				len1 = step - tem;

				ne = secondList;
				while (ne && len2 < step)
				{
					ne = ne->next;
					len2++;
				}
				
				ListNode * h = combinateList(firstList, secondList, len1, len2);
				lastHead->next = h;
				lastHead = h;
				tem = 0;
				while (tem<len1+len2-1)
				{
					lastHead = lastHead->next;
					tem++;
				}
			}
			lastHead->next = NULL; //很重要,最后一个归并排序的链表需要设置成为链表最终的结束位置,
			//其实每次都需要,但是中间归并排序这个尾巴都会被复制为下一个归并排序结果的头
			head = newHead->next;//重新将目前部分排好序的链表头返回到下次循环的头
			step *= 2;//增加步长
		}
		delete ne;
		return head;

	}

	ListNode * combinateList(ListNode * firstList, ListNode * secondList, int firstLength, int secondLength)
	{
		if ((firstList == NULL && secondList == NULL) || firstLength < 0 || secondLength < 0)
		{
			return NULL;
		}
		if (firstList != NULL && secondList == NULL)
		{
			return firstList;
		}
		if (firstList == NULL && secondList != NULL)
		{
			return secondList;
		}

		ListNode * result, *cur;
		ListNode * firstHead = firstList, *secondHead = secondList;
		int step1 = 0, step2 = 0;
		if (firstHead->val < secondHead->val)
		{
			result = firstHead;
			firstHead = firstHead->next;
			step1++; 
		}
		else
		{
			result = secondHead;
			secondHead = secondHead->next;
			step2++;
		}
		cur = result;
		while (firstHead !=NULL && secondHead != NULL && step1 < firstLength && step2 < secondLength)
		{
			if (firstHead->val < secondHead->val)
			{
				cur->next = firstHead;
				cur = cur->next;
				firstHead = firstHead->next;
				step1++;
			}
			else
			{
				cur->next = secondHead;
				cur = cur->next;
				secondHead = secondHead->next;
				step2++;
			}
		}
		if (step1 != firstLength && step2 != secondLength)
		{
			return NULL;
		}
		if (step1 == firstLength)
		{
			cur->next = secondHead;
		}
		else
		{
			cur->next = firstHead;
		}
		return result;
	}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值