合并两个有序链表(递归)

题目描述

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

先看一下代码

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) { val = x; }* }*/
class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {if (l1==null) return l2 ; if (l2==null) return l1 ; if (l1.val<l2.val) {l1.next = mergeTwoLists(l1.next,l2) ; return l1 ; }else {l2.next = mergeTwoLists(l1,l2.next) ;return  l2 ;  }}
}

分析

这个算法,来自大名鼎鼎的归并排序,你一下子看不懂很正常,你可以这么来理解,两个链表之间通过比大小玩连连看,在链表一或链表二最后的结点,开始往回走,把之前比较的结点按序连成一条线,最终返回的就是一个合并好的链表

如果还是理解不了,你可以以一个极端的例子,去代入这段代码,帮助你理解

(1,2,3)
(4,5,6)

性能分析

时空复杂度皆为O(m+n)两个链表的结点总和,在这道题中,不一定每个结点都会被访问到,如上面举例的极端情况,所以实际时空复杂度应该是小于O(m+n)
==========update by 2020 4/16 ========

可运行代码

#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0#define MAXSIZE 20 /* 存储空间初始分配量 */typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */Status visit(ElemType c)
{printf("%d ", c);return OK;
}typedef struct ListNode
{ElemType val;struct ListNode *next;
}ListNode;
typedef struct ListNode *LinkList; /* 定义LinkList *//* 初始化顺序线性表 */
Status InitList(LinkList *L)
{*L = (LinkList)malloc(sizeof(ListNode)); /* 产生头结点,并使L指向此头结点 */if (!(*L)) /* 存储分配失败 */return ERROR;(*L)->val = NULL;(*L)->next = NULL; /* 指针域为空 */return OK;
}/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(LinkList *L, int i, ElemType e)
{int j;LinkList p, s;p = *L;j = 1;while (p && j < i)     /* 寻找第i个结点 */{p = p->next;++j;}if (!p || j > i)return ERROR;   /* 第i个元素不存在 */s = (LinkList)malloc(sizeof(ListNode));  /*  生成新结点(C语言标准函数) */s->val = e;s->next = p->next;      /* 将p的后继结点赋值给s的后继  */p->next = s;          /* 将s赋值给p的后继 */return OK;
}/* 初始条件:顺序线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
Status ListTraverse(LinkList L)
{LinkList p = L->next;while (p){visit(p->val);p = p->next;}printf("\n");return OK;
}LinkList mergeTwoLists(LinkList l1, LinkList l2) {/*递归出口*/if (l1 == NULL) {return l2;}if (l2 == NULL) {return l1;}/*递归操作*/if (l1->val < l2->val) {l1->next = mergeTwoLists(l1->next, l2);return l1;}else {l2->next = mergeTwoLists(l1, l2->next);return l2;}}int main()
{LinkList L;LinkList L2;LinkList L3; ElemType e;Status i;int j, k;/*1.初始化单链表*/i = InitList(&L);/*2.依次采用尾插法插入abcde元素*/ListInsert(&L, 1, 1);ListInsert(&L, 2, 2);ListInsert(&L, 3, 4);i = InitList(&L2);ListInsert(&L2, 1, 1);ListInsert(&L2, 2, 3);ListInsert(&L2, 3, 4);L3 = mergeTwoLists(L, L2); /*11.输出单链表*/printf("输出单链表\n");ListTraverse(L3);system("pause");return 0;}

合并两个有序链表(递归)相关推荐

  1. 合并两个有序链表——递归与迭代

    力扣刷题总结 一.前言 二.合并两个有序链表 1.题意 2.示例 3.题解 方法一递归算法 思路分析 代码解析 方法二迭代算法 思路分析 代码解析 总结 一.前言 最近几天有点忙,没来得及更新我的力扣 ...

  2. [递归|迭代] leetcode 21 合并两个有序链表

    [递归|迭代] leetcode 21 合并两个有序链表 1.题目 题目链接 将两个升序链表合并为一个新的升序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2 ...

  3. 【LeetCode】【HOT】21. 合并两个有序链表(递归)

    [LeetCode][HOT 100]21. 合并两个有序链表 文章目录 [LeetCode][HOT 100]21. 合并两个有序链表 package hot;import java.util.Ar ...

  4. 算法:合并两个有序链表

    题目 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出:1- ...

  5. 20190827:(leetcode习题)合并两个有序链表

    合并两个有序链表 题目 大致思路 代码实现 题目 大致思路 本题的思路来讲,可以想见是和数组之类的类似,每次取出一个最小的值,取n次之后得到新链,最容易想到递归方法.每次调用函数时得到新的ListNo ...

  6. leetcode 21 java_LeetCode 21. 合并两个有序链表

    LeetCode 21. 合并两个有序链表 题目 将两个升序链表合并为一个新的升序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1-> ...

  7. 力扣合并两个有序链表

    力扣合并两个有序链表 1.要求 2.思路及代码 3.问题 1.要求 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1-& ...

  8. 21. 合并两个有序链表 JavaScript实现

    21. 合并两个有序链表 合并有序链表 一.递归 递归详解 /*** Definition for singly-linked list.* function ListNode(val, next) ...

  9. 【LeetCode】21、合并两个有序链表

    21.合并两个有序链表 题目: 将两个升序链表合并为一个新的 升序 链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例1: 输入:l1 = [1,2,4], l2 = [1,3,4] ...

最新文章

  1. Unicode 和 UTF-8关系
  2. 第十三周项目二-动物这样叫(3)
  3. 宇泽电影工作室网页HTML语言,4.4宇泽国际旅行社网页制作
  4. php ob静态缓存
  5. Angular开发模式下的setNgReflectProperties函数
  6. sql中问号是干什么的??
  7. MySQL Cookbook 学习笔记-04
  8. 红帽Linux7怎么修改网卡名称,新安装的Centos 7系统怎么将网卡名称改为eth0?
  9. Flume案例Ganglia监控
  10. 大数据学习笔记24:利用MR改造Zebra项目
  11. 服务器普通用户无法使用conda
  12. 企业研发人员配备比例_高新企业研发人员占比多少
  13. 公元2011年6月20日,我在博客园安家了,大家祝贺吧!
  14. 模式识别(五)聚类的几种算法
  15. 常见的激励函数和损失函数
  16. 串口转WIFI的工作方式理解
  17. EXCEL常用函数——计算统计函数
  18. 如何在控制台创建文件夹
  19. STM32F767 QUADSPI 的基本用法
  20. mysql trans begin_[原创]MySQL RR隔离级别下begin或start transaction开启事务后的可重复读?...

热门文章

  1. 用Canvas实现刮刮卡功能的研究与实践
  2. 一加手机怎么样?来看看这个测评
  3. 【mysql5.1.47会报一个时间戳设置未null的错】
  4. monai.tansforms.xxx 常用函数作用
  5. JVM命令 jstat
  6. sql server management studio 已停止工作_便利店员工的每日工作流程
  7. 计算机科学与技术情话,一个专业一句情话,你被哪个专业甜到了?
  8. Linux修改IP地址--修改为静态IP
  9. 安装Oracle Enterprise Manager Cloud Control 客户端
  10. mysql 从第几个字符串开始截取_Mysql 字符串截取