单链表的合并算法_每日一道面试题系列 如何合并两个有序链表

1fb6993bd900b511e9b3ef6df9f73004.gif

题目描述

c3d34258a187abc9dabc3c2f78a5b984.png

来源:阿里巴巴笔试题                         难度系数:★★★☆☆                   考察频率:★★★★☆

题目描述:

已知两个链表 head1 和 head2 各自有序(例如升序排列),请把它们合并成一个链表,要求合并后的链表依然有序。

本题摘选自猿媛之家出版的《Python 程序员面试算法宝典》一书中。

分析解答

c3d34258a187abc9dabc3c2f78a5b984.png

分析

主要思路为:

分别用指针 head1,head2 来遍历两个链表,如果当前 head1 指向的数据小于 head2 指向的数据,则将 head1 指向的结点归入合并后的链表中,否则,将 head2 指向的结点归入合并后的链表中。如果有一个链表遍历结束,则把未结束的链表连接到合并后的链表尾部。

下图以一个简单的示例为例介绍合并的具体方法:

3dea22e6162fbe7620b3700df945e5fe.png

由于链表按升序排列,首先通过比较链表第一个结点中元素的大小来确定最终合并后链表的头结点;接下来每次都找两个链表中剩余结点的最小值链接到被合并的链表后面,如上图中的虚线所示。

解答

解答代码

# -*- coding: utf-8 -*-"""Created on Sat Nov 10 12:30:27 2018@author: Administrator"""class  LNode:      def  __init__(self):          self.data=None        self.next=None # 方法功能:构造链表 def  ConstructList(start):    i=start    head=LNode()    head.next=None    cur=head    while  i<7:        tmp=LNode()        tmp.data=i        tmp.next=None        cur.next=tmp        cur=tmp        i +=2     return  head  def  PrintList(head):    cur=head.next    while  cur!=None:        print  (cur.data,'',end='')        cur=cur.next"""方法功能:合并两个升序排列的单链表输入参数:head1与head2代表两个单链表返回值:合并后链表的头结点"""def  Merge(head1,head2):    if  head1==None or head1.next==None:        return  head2    if  head2==None or head2.next==None:        return  head1    cur1=head1.next # 用来遍历head1    cur2=head2.next # 用来遍历head2    head=None  # 合并后链表的头结点    cur=None # 合并后的链表在尾结点    # 合并后链表的头结点为第一个结点元素最小的那个链表的头结点    if  cur1.data > cur2.data:        head=head2        cur=cur2        cur2=cur2.next    else:        head=head1        cur=cur1        cur1=cur1.next            # 每次找链表剩余结点的最小值对应的结点连接到合并后链表的尾部    while  cur1!=None and  cur2!=None:        if  cur1.data < cur2.data:            cur.next=cur1            cur=cur1            cur1=cur1.next        else:            cur.next=cur2            cur=cur2            cur2=cur2.next    # 当遍历完一个链表后把另外一个链表剩余的结点链接到合并后的链表后面    if  cur1!=None:        cur.next=cur1    if  cur2!=None:        cur.next=cur2    return  head  if  __name__=="__main__":    head1=ConstructList(1)    head2=ConstructList(2)    print  ("head1: ",end='')    PrintList(head1)    print  ("\nhead2: ",end='')    PrintList(head2)    print  ("\n合并后的链表:",end='')    head=Merge(head1,head2)    PrintList(head)

程序的运行结果为:

 head1: 1 3 5 head2: 2 4 6合并后的链表:1 2 3 4 5 6

算法性能分析:

以上这种方法只需要对链表进行一次遍历,因此,时间复杂度为 O(n)。另外由于只需要几个指针变量来保存结点的地址信息,因此,空间复杂度为 O(1)。

感谢您的阅读,有任何问题欢迎评论区留言。

· END ·

8fdd1004e06d34f9267409ef951a5016.gif

31bc37a6d5d75e14baa42c628a31c2fa.png

欢迎加入猿媛之家QQ群获取更多交流:496588733

本公众号拥有优而全的高效复习资料(导航栏做了统一整理目录,持续更新...),旨在为您的面试求职保驾护航,提高您的职场竞争力,感谢您的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值