Leecode热题100---148:排序链表

题目:
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

思路:归并排序
先将链表从中间分为左边和右边,再对左边和右边分别进行划分,直到只有一个元素或没有元素,再开始合并;
即:
1、拆开链表方法:
fast-slow法,双指针,一个每次走两步,一个走一步,快指针走到结尾,慢指针就这链表中间,并用pre作为慢指针的前驱,通过pre将链表分为左边[head,pre],右边[slow,fast]两部分;
2、合并两个链表的方法:
将两段的头结点值进行比较,把小的放入结果链表中,直到有一个为空,把不空的直接链接到后面。

C++:

#include<iostream>
using namespace std;

struct ListNode
{
	ListNode();    // 无参构造函数,
	int val;
	ListNode *next;
	ListNode(int x)  // 有参构造函数
	{
		val = x;
		next = nullptr;
	}
	ListNode(int x, ListNode *next)
	{
		val = x;
		next = next;
	}
};

class Solution {
public:
	//快慢指针分割链表函数
	ListNode* mergesort(ListNode* head)
	{
		//如果只有一个结点或者没有结点,直接返回
		if (head == nullptr || head->next == nullptr)
		{
			return head;
		}
		ListNode *slow = head;   //慢指针,每次走一步
		ListNode *fast = head;   //快指针,每次走两步
		ListNode *pre = nullptr; //慢指针的前驱

		while (fast != nullptr && fast->next != nullptr)
		{
			pre = slow;
			slow = slow->next;
			fast = fast->next->next;
		}
		//此时slow指针指向中间结点,用pre指针把链表从中间断开,分为[head,pre],[slow,fast]两段
		pre->next = nullptr;
		ListNode *L = sortList(head); //左边
		ListNode *R = sortList(slow); //右边
		return merge(L, R);            //对两边进行归并

	}

	// 非递归归并函数
	ListNode *merge(ListNode *L, ListNode*R)
	{
		ListNode *dump = new ListNode(0);
		ListNode *cur = dump;

		//两边都不为空,选出两边最小的链接到cur后面
		while (L != nullptr && R != nullptr)
		{
			if (L->val <= R->val)
			{
				cur->next = L;
				L = L->next;
				cur = cur->next;
			}
			else
			{
				cur->next = R;
				R = R->next;
				cur = cur->next;
			}
		}

		//如果左边空了,右边没空,把右边剩下的链接上去
		if (L == nullptr)
		{
			cur->next = R;
		}
		//如果右边空了,左边没空,把左边剩下的链接上去
		if (R == nullptr)
		{
			cur->next = L;
		}
		return dump->next;
	}

	ListNode *sortList(ListNode *head)
	{
		return mergesort(head);
	}
};

python:
思路:归并排序 (快慢指针+合并有序链表)
在这里插入图片描述

# 链接:
# https://leetcode.cn/problems/sort-list/solutions/687028/pai-xu-lian-biao-gui-bing-pai-xu-kuai-ma-2v1b/?envType=study-plan-v2&envId=top-100-liked

class ListNode(object):
    def __init__(self, val=0,next=None):
        self.val = val
        self.next = next

class Solution(object):
    def sortList(self,head):
        if not head or head.next: return head
        left_end = self.find_mid(head)
        mid = left_end.next
        left_end.next = None
        left, right = self.sortList(head), self.sortList(mid)
        return self.merged(left,right)

    # 快慢指针查找链表中点
    def find_mid(self,head):
        if head is None or head.next is None:return head
        slow, fast = head,head.next
        while fast is not None and fast.next is not None:
            slow=slow.next
            fast=fast.next.next
        return slow
    
    # 合并有序链表
    def merged(self,left,right):
        res = ListNode()
        h = res
        while left and right:
            if left.val < right.val:
                h.next,left = left,left.next
            else:
                h.next,right = right, right.next
            h = h.next
        h.next = left if left else right
        return res.next
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ghx3110

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值