题目描述
已知两个链表head1、head2各自有序(如升序排列),请把它们合并为一个链表,要求合并后的链表依然有序。
解题思路
分别用指针head1、head2来遍历两个链表,如果当前head1指向的数据小于head2指向的数据,则将head1指向的结点归入合并后的链表中,否则将head2指向的结点归入合并后的链表中。如果有一个链表遍历结束,则把未结束的链表连接到合并后的链表尾部。
class LNode {
/**
* 数据域
*/
int data;
/**
* 下一个结点的引用
*/
LNode next;
}
public class Test9 {
public static LNode constructList(int start){
/**
* @Author: JavaRecord
* @Description:构造链表
* @Param [start]
* @Return linked.list1.LNode
* @Date 2020/8/19
* @Time 14:31
*/
int i=start;
LNode head=new LNode();
head.next=null;
LNode tmp=null;
LNode cur=head;
for(;i<7;i+=2){
tmp=new LNode();
tmp.data=i;
tmp.next=null;
cur.next=tmp;
cur=tmp;
}
return head;
}
public static LNode merge(LNode head1,LNode head2){
/**
* @Author: JavaRecord
* @Description:合并两个升序排列的单链表
* @Param [head1, head2]
* @Return linked.list1.LNode
* @Date 2020/8/19
* @Time 14:36
*/
if(head1==null||head1.next==null){
return head2;
}
if(head2==null||head2.next==null){
return head1;
}
//用来遍历head1
LNode cur1=head1.next;
//用来遍历head2
LNode cur2=head2.next;
//合并后链表的头结点
LNode head=null;
//合并后的链表的尾结点
LNode cur=null;
//合并后链表的头结点为第一个结点元素最小的那个链表的头结点
if(cur1.data>cur2.data){
head=head2;
cur=cur2;
cur2=cur2.next;
}else{
head=head1;
cur=cur1;
cur1=cur1.next;
}
//每次找链表剩余结点的最小值对应的结点连接到合并后链表的尾部
while (cur1!=null&&cur2!=null){
if(cur1.data<cur2.data){
cur.next=cur1;
cur=cur1;
cur1=cur1.next;
}else{
cur.next=cur2;
cur=cur2;
cur2=cur2.next;
}
}
//当遍历完一个链表后把另外一个链表的剩余结点连接到合并后的链表后面
if(cur1!=null){
cur.next=cur1;
}
if(cur2!=null){
cur.next=cur2;
}
return head;
}
public static void printList(LNode head){
/**
* 打印链表
*/
for(LNode cur=head.next;cur!=null;cur=cur.next){
System.out.print(cur.data+" ");
}
}
public static void main(String[] args){
LNode head1=constructList(1);
LNode head2=constructList(2);
System.out.print("head1:");
printList(head1);
System.out.print("\nhead2:");
printList(head2);
System.out.print("\n合并后的链表:");
LNode head=merge(head1,head2);
printList(head);
}
}
算法性能分析
对链表进行一次遍历,时间复杂度为O(n);只需要几个指针变量来保存结点的地址信息,空间复杂度为O(1)