题目描述
来源:阿里巴巴笔试题 难度系数:★★★☆☆ 考察频率:★★★★☆题目描述:
已知两个链表 head1 和 head2 各自有序(例如升序排列),请把它们合并成一个链表,要求合并后的链表依然有序。
本题摘选自猿媛之家出版的《Python 程序员面试算法宝典》一书中。
分析解答
分析
主要思路为:
分别用指针 head1,head2 来遍历两个链表,如果当前 head1 指向的数据小于 head2 指向的数据,则将 head1 指向的结点归入合并后的链表中,否则,将 head2 指向的结点归入合并后的链表中。如果有一个链表遍历结束,则把未结束的链表连接到合并后的链表尾部。
下图以一个简单的示例为例介绍合并的具体方法:
由于链表按升序排列,首先通过比较链表第一个结点中元素的大小来确定最终合并后链表的头结点;接下来每次都找两个链表中剩余结点的最小值链接到被合并的链表后面,如上图中的虚线所示。
解答
解答代码
# -*- 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 ·
欢迎加入猿媛之家QQ群获取更多交流:496588733
本公众号拥有优而全的高效复习资料(导航栏做了统一整理目录,持续更新...),旨在为您的面试求职保驾护航,提高您的职场竞争力,感谢您的支持!