sort-list(链表排序)

本文介绍两种链表排序方法:一种是将链表转换为数组,排序后再转换回链表;另一种是对链表进行归并排序,通过快慢指针找到中点,递归分割链表并合并。

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

https://www.nowcoder.com/practice/d75c232a0405427098a8d1627930bea6?tpId=46&tqId=29033&tPage=1&rp=1&ru=/ta/leetcode&qru=/ta/leetcode/question-ranking

两个思路:

思路一:把链表的值复制到一个数组里面去, 然后对这个数组排序,然后再把值复制回来原来的链表即可。

class Solution {
public:
    ListNode *sortList(ListNode *head) {
        
		if(head == nullptr)
			return nullptr;

		vector<int>res;

		ListNode * p = head;

		while( p  )//把链表的值复制到数组里面去。
		{
			res.push_back (p -> val);
			p = p->next;
		

		}

		sort(res.begin(), res.end());//排序

		ListNode * pList = head;

		//把数组的值复制回原来的链表。
		for(int i = 0; i < res.size(); i++){
		
			pList->val = res[i];
			pList = pList->next;

		}
		return head;

	
    }
};

思路二: 对链表进行归并排序。只不过在二分链表的时候和对普通的数组二分做法不一样。

设定一慢指针,快指针, 同时用pre记录慢指针的前驱节点。每一次快指针走两步,慢指针走一步,当快指针尾部指向空,即到链表的尾部的时候,可以把链表二分为两个链表了。不断的对链表进行二分,直到不能再分了,然后对链表进行合并排序。

class Solution {
public:
    ListNode *sortList(ListNode *head) {
        if(head == nullptr)
			return nullptr;

		if(head->next == nullptr)//一个节点不用排序了
			return head;

		ListNode * slow = head;//慢指针
		ListNode * fast = head;//快指针
		ListNode * pre = nullptr;//记录慢指针的前驱节点

		while(fast && fast->next)//查找链表的中点
		{
			pre = slow;
			slow = slow->next;
			fast = fast->next->next;//快指针走两步
			

		}

		pre->next = nullptr;//把链表分成两部分

		ListNode * left = sortList(head);//左边的链表二分
		ListNode * right = sortList(slow);//对右边的链表二分
		
		return merge(left, right);//合并排序

    }

	ListNode * merge(ListNode * p1, ListNode * p2)
	{
		if(p1 == nullptr)
			return p2;
		if(p2 == nullptr)
			return p1;

		if(p1->val <= p2->val)
		{
			p1->next = merge(p1->next, p2);//对剩余部分合并排序
			return p1;
		}
		else
		{
			p2->next = merge(p1, p2->next);
			return p2;
		}
	}
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值