链表的归并排序

两种方法
递归法(自顶向下法)

迭代法(自底向上法)

递归法(自顶向下法)

这里链表与数组不同的是链表无法随机访问,在数组中我们都能精准的找到中间位置,这里我们采用快慢指针来确定中间节点,然后通过递归到单个元素然后分割链表,再链接链表(下面将一一讲解)

快慢指针确定中间节点

/*head为已知条件*/
Listnode* tail=nullptr;
Listnode* slow=head;
Listnode* fast=head; 
while(fast!=tail)         //快指针多移动一次到尾时,慢指针则为中间节点
{ 
   slow=slow->next;
   fast=fast->next;
   if(fast!=tail)
   {
      fast=fast->next;
   }
   Listnode* mid=slow;    //中间节点
}

分割链表

ListNode* apart_list(ListNode* head,ListNode* tail)
{
    if(head==nullptr) return nullptr;
    if(head->next==tail) return head;
    Listnode* slow=head;
    Listnode* fast=head; 
    while(fast!=tail)         //快指针多移动一次到尾时,慢指针则为中间节点
    { 
       slow=slow->next;
       fast=fast->next; 
       if(fast!=tail)         //头闭尾开只有一个元素head 无法继续分割返回head节点 
       { 
          fast=fast->next;
       }
       Listnode* mid=slow;    //中间节点
    }
    
    /*这里的merge为合并函数*/
    /*我们这里递归分割左右链表,递归到只有一个元素无法分割后链接两边节点*/
    return merge(apart_list(head,mid),apart_list(mid,tail));
}
/*
    假如链表如下:
    1   4   3   5   2  
第一次分割1,nullptr中间节点为3 也就是  return merge(apart_list(1,3),apart_list(3,nullptr)) 
第二次分割1,3中间节点为2  然后 return  merge(apart_list(1,2),apart_list(2,3))   
第三次分割1,2无法进行分割 此时满足head->next=tail 1节点下一节点置空 返回1节点
第四次分割2,3同理 置空2节点的下一节点后返回2节点
然后通过执行merge(2,3)将分割的单个节点2和3有序链接  返回给上一级递归
同理3,nullptr也是如此
*/

链接链表

这个就简单了就是合并两个有序链表

 ListNode* merge(ListNode* l,ListNode* r)
{
   ListNode* temp=new ListNode(0);
   ListNode* l_now=l;
   ListNode* r_now=r;
   ListNode* now=temp;
   
   /*都有元素则比较大小*/
   while(l_now!=nullptr&&r_now!=nullptr)
   {
      if(l_now->val<=r_now->val)
      {
          now->next=l_now;
          l_now=l_now->next;
      }  
      else 
      {
          now->next=r_now;
          r_now=r_now->next;
      }
      now=now->next;
   }
   
   /*链接剩下的元素*/
   if(l_now!=nullptr)
   {
       now->next=l_now;
   }
   else now->next=r_now;
   return temp->next;
}

完整代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* apart_list(ListNode* head,ListNode* tail)
    {
        if(head==nullptr) return nullptr;
        if(head->next==tail)
        {
            head->next=nullptr;
            return head;
        }
        ListNode* slow=head,*fast=head;
        while(fast!=tail)
        {
            slow=slow->next;
            fast=fast->next;
            if(fast!=tail)
            {
                fast=fast->next;
            }
        }
        ListNode* mid=slow;
        return merge(apart_list(head,mid),apart_list(mid,tail));
    }
    ListNode* merge(ListNode* l,ListNode* r)
    {
        ListNode* temp=new ListNode(0);
        ListNode* l_now=l;
        ListNode* r_now=r;
        ListNode* now=temp;
        while(l_now!=nullptr&&r_now!=nullptr)
        {
            if(l_now->val<=r_now->val)
            {
                now->next=l_now;
                l_now=l_now->next;
            }
            else
            {
                now->next=r_now;
                r_now=r_now->next;
            }
            now=now->next;
        }
        if(l_now!=nullptr)
        {
           now->next=l_now;
        }
        else if(r_now!=nullptr)
        {
           now->next=r_now;
        }
        return temp->next;
    }
    ListNode* sortList(ListNode* head) {
        return apart_list(head,nullptr);
    }
};

时间复杂度为O(nlogn)空间复杂度为O(logn)

自底向上法

和数组一样我们需要不断的增加分区间的距离

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if(head==nullptr)
        {
            return head;
        }
        int length=0;
        ListNode* node=head;
        while(node!=nullptr)
        {
            length++;
            node=node->next;
        } 
        ListNode* temp=new ListNode(0,head);
        for(int len=1;len<length;len*=2)     //增加半区间
        {
            ListNode* pre=temp,*now=temp->next;
            while(now!=nullptr)
            {
                ListNode* head1=now;
                for(int i=1;i<len&&now->next!=nullptr;i++)
                {
                    now=now->next;
                }
                ListNode*head2=now->next;
                now->next=nullptr;            //分割
                now=head2;
                for(int i=1;i<len&&now!=nullptr&&now->next!=nullptr;i++)
                {
                    now=now->next;
                }
                ListNode* next=nullptr;
                if(now!=nullptr)
                {
                    next=now->next;
                    now->next=nullptr;
                }
                ListNode* marged=merge(head1,head2);
                pre->next=marged;
                while(pre->next!=nullptr)
                {
                    pre=pre->next;
                }
                now=next;
            } 
        }
        return temp->next;
    }
    ListNode* merge(ListNode* l,ListNode* r)
    {
        ListNode* temp=new ListNode(0);
        ListNode* l_now=l;
        ListNode* r_now=r;
        ListNode* now=temp;
        while(l_now!=nullptr&&r_now!=nullptr)
        {
            if(l_now->val<=r_now->val)
            {
                now->next=l_now;
                l_now=l_now->next;
            }
            else
            {
                now->next=r_now;
                r_now=r_now->next;
            }
            now=now->next;
        }
        if(l_now!=nullptr)
        {
           now->next=l_now;
        }
        else if(r_now!=nullptr)
        {
           now->next=r_now;
        }
        return temp->next;
    }
};

时间复杂度为O(logn)空间复杂度为O(n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/910845.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

8.机器学习--决策树

(⊙﹏⊙)下周有要开组会&#xff0c;不知道该说啥&#xff0c;啊啊啊啊&#x1f62b; 目录 1.基本概念 2.ID3算法 3.C4.5算法 4.CART算法 5.连续与缺失值处理 5.1.连续值处理 5.2.缺失值处理 6.剪枝处理 6.1.预剪枝策略 6.2.后剪枝策略 7.实例代码 1.基本概念 提…

C#的6种常用集合类

一.先来说说数组的不足&#xff08;也可以说集合与数组的区别&#xff09;&#xff1a; 1.数组是固定大小的&#xff0c;不能伸缩。虽然System.Array.Resize这个泛型方法可以重置数组大小&#xff0c;但是该方法是重新创建新设置大小的数组&#xff0c;用的是旧数组的元素初始…

以太网交换安全:MAC地址漂移

一、什么是MAC地址漂移&#xff1f; MAC地址漂移是指设备上一个VLAN内有两个端口学习到同一个MAC地址&#xff0c;后学习到的MAC地址表项覆盖原MAC地址表项的现象。 MAC地址漂移的定义与现象 基本定义&#xff1a;MAC地址漂移发生在一个VLAN内的两个不同端口学习到相同的MAC地…

qt QHttpMultiPart详解

1. 概述 QHttpMultiPart是Qt框架中用于处理HTTP多部分请求的类。它类似于RFC 2046中描述的MIME multipart消息&#xff0c;允许在单个HTTP请求中包含多个数据部分&#xff0c;如文件、文本等。这种多部分请求在上传文件或发送带有附件的邮件等场景中非常有用。QHttpMultiPart类…

【SQL实验】高级查询(难点.三)含附加数据库操作

完整代码在文章末尾【代码是自己的解答&#xff0c;并非标准答案&#xff0c;也有可能写错&#xff0c;文中可能会有不准确或待完善之处&#xff0c;恳请各位读者不吝批评指正&#xff0c;共同促进学习交流】 将素材中的“学生管理”数据库附加到SQL SERVER中&#xff0c;完成以…

基于Spring Boot+Vue的助农销售平台(协同过滤算法、限流算法、支付宝沙盒支付、实时聊天、图形化分析)

&#x1f388;系统亮点&#xff1a;协同过滤算法、节流算法、支付宝沙盒支付、图形化分析、实时聊天&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk1…

std::copy

std::copy 是 C 标准库中的一个算法&#xff0c;用于将一个序列中的元素复制到另一个位置。这个算法定义在 <algorithm> 头文件中。 --- 函数原型 std::copy 有几个不同的重载版本&#xff0c;但以下是最常用的两个&#xff1a; template <class InputIterator, c…

Linux之sed命令详解

文章目录 &#x1f34a;自我介绍&#x1f34a;sed概述&#x1f34a;sed语法讲解格式&#xff1a;options 命令选项{commmand}[flags] &#x1f34a;场景训练 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff…

现代Web开发:React Hooks深入解析

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 现代Web开发&#xff1a;React Hooks深入解析 现代Web开发&#xff1a;React Hooks深入解析 现代Web开发&#xff1a;React Hook…

大语言模型(LLM)入门级选手初学教程 III

指令微调 一、指令数据的构建 包括任务描述&#xff08;也称为指令&#xff09;、任务输入-任务输出以及可选的示例。 Self-Instruct 指令数据生成&#xff1a;从任务池中随机选取少量指令数据作为示例&#xff0c;并针对Chat-GPT 设计精细指令来提示模型生成新的微调数据…

算法工程师重生之第四十六天(字符串接龙 有向图的完全可达性 岛屿的周长)

参考文献 代码随想录 一、字符串接龙 题目描述 字典 strList 中从字符串 beginStr 和 endStr 的转换序列是一个按下述规格形成的序列&#xff1a; 1. 序列中第一个字符串是 beginStr。 2. 序列中最后一个字符串是 endStr。 3. 每次转换只能改变一个字符。 4. 转换过程…

魅力标签云,奇幻词云图 —— 数据可视化新境界

目录 目的原理详解建议 标签云&#xff1a;用于汇总生成的标签&#xff0c;一般是独立词汇运行前的准备代码示例 词云&#xff1a;对本文中出现频率较高的词&#xff0c;视觉上突出显示总结 目的 掌握文本与文档可视化&#xff1a;使用特定软件或编程语言&#xff08;如Python…

云计算答案

情境一习题练习 一、选择题 1、在虚拟机VMware软件中实现联网过程&#xff0c;图中箭头所指的网络连接方式与下列哪个相关&#xff08; C &#xff09;。 A.仅主机模式 B.桥接 C.NAT D.嫁接 2、请问下图这个虚拟化架构属于什么类型&#xff08; A …

【测试】【Debug】vscode pytest 找不到测试用例测试文件 行号部位没有绿色箭头

出现这种情况首先检查&#xff1a; 是否安装pytest点击vscode的这个图标如果其中都是空的&#xff0c;没有识别上&#xff0c;并且写好的.py测试文件的行号前面没有运行符号&#xff0c;要检查名称是否按照pytest的要求写&#xff0c;不然会识别不到。 命名规则注意&#xff1…

Echats柱状图的横坐标用图片显示

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>图片作为横坐标示例 - ECharts</title><!-…

D-ID 推出能模仿用户的头部动作以及实时互动的 AI 头像

D-ID 宣布推出两种新型 AI 头像 — — Express 和 Premium&#xff0c;旨在提升内容创作的灵活性和人性化。这些头像将为企业在营销、销售和客户支持等领域的视频制作提供便利。用户只需少量文本输入和视觉数据&#xff0c;即可生成更自然的商业视频。 Express 头像可以通过约一…

vue使用canves把数字转成图片验证码

<canvas id"captchaCanvas" width"100" height"40"></canvas>function drawCaptcha(text) {const canvas document.getElementById(captchaCanvas);const ctx canvas.getContext(2d);// 设置背景颜色ctx.fillStyle #f0f0f0;ctx.f…

mybatisgenerator生成mapper时报错

本想使用generator自动生成model和mapper&#xff0c;没想到插件执行的时候报如下错误。 Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.2:generate (default-cli) on project ywq-mybatis-tools: Execution default-cli of goal org.myb…

【无标题】西安交通大学提出少锚点的端到端车道线检测算法Polar R-CNN

Abstract 车道线检测在自动驾驶中是一个关键且充满挑战的任务&#xff0c;特别是在实际场景中&#xff0c;由于车道线可能因其他车辆而被遮挡、形状纤细且长度较长&#xff0c;检测难度增大。现有基于锚点的检测方法通常依赖于预设的锚点来提取特征&#xff0c;并随后对车道线…

Vue + Vant Picker实现省市区三级联动

一、picker选择器的数据由columns属性控制&#xff0c;columns中有几个元素就代表该选择器有多少级&#xff0c;通过change方法来给对应列赋值 this.columns [{values: citys,className: "column1",defaultIndex: 0,flex: 1, //控制每列的宽度},{values: citys[0].…