一、概述
- 合并两个单向有序链表如:
- 链表A:1-3-5
- 链表B:2-4
- 合并结果:1-2-3-4-5
- 什么是单向链表:https://blog.csdn.net/oJueQiang123456/article/details/86384046
二、代码
public class Link {
public static void main(String[] args) {
// 构造链表A
LinkNode linkNodeA1 = new LinkNode(1);
LinkNode linkNodeA2 = new LinkNode(3);
LinkNode linkNodeA3 = new LinkNode(5);
linkNodeA1.next = linkNodeA2;
linkNodeA2.next = linkNodeA3;
// 构造链表B
LinkNode linkNodeB1 = new LinkNode(2);
LinkNode linkNodeB2 = new LinkNode(4);
linkNodeB1.next = linkNodeB2;
// 合并链表
LinkNode linkNode = merge(linkNodeA1, linkNodeB1);
System.out.println(linkNode.obj);
while (null != linkNode.next) {
linkNode = linkNode.next;
System.out.println(linkNode.obj);
}
}
/**
* 常规:按顺序合并链表
* @param ln1
* @param ln2
* @return
*/
public static LinkNode merge(LinkNode ln1, LinkNode ln2) {
if(null == ln1) return ln2;
if(null == ln2) return ln1;
// 获取头结点
LinkNode head = null;
if(ln1.obj <= ln2.obj) {
head = ln1;
ln1 = ln1.next;
} else {
head = ln2;
ln2 = ln2.next;
}
// temp 指向每一次合并之后的最后一个结点:用于指定下一个结点
LinkNode cur = head;
while (null != ln1 && null != ln2) {
if(ln1.obj <= ln2.obj) {
cur.next = ln1;
cur = ln1;
ln1 = ln1.next;
} else {
cur.next = ln2;
cur = ln2;
ln2 = ln2.next;
}
}
// 当其中一个链表为空时
if(null == ln1) {
cur.next = ln2;
} else {
cur.next = ln1;
}
return head;
}
/**
* 添加虚拟头结点:按顺序合并链表
* @param ln1
* @param ln2
* @return
*/
public static LinkNode merge2(LinkNode ln1, LinkNode ln2) {
if(null == ln1) return ln2;
if(null == ln2) return ln1;
// 设置虚拟头结点
LinkNode head = new LinkNode(10000);
// temp 指向每一次合并之后的最后一个结点:用于指定下一个结点
LinkNode temp = head;
while (null != ln1 && null != ln2) {
if(ln1.obj <= ln2.obj) {
temp.next = ln1;
temp = ln1;
ln1 = ln1.next;
} else {
temp.next = ln2;
temp = ln2;
ln2 = ln2.next;
}
}
if(null == ln1) {
temp.next = ln2;
} else {
temp.next = ln1;
}
return head.next;
}
/**
* 递归:按顺序合并链表
* @param ln1
* @param ln2
*/
public static LinkNode merge3(LinkNode ln1, LinkNode ln2) {
if(null == ln1) return ln2;
if(null == ln2) return ln1;
if(ln1.obj <= ln2.obj) {
ln1.next = merge3(ln1.next, ln2);
return ln1;
} else {
ln2.next = merge3(ln1, ln2.next);
return ln2;
}
}
/**
* 单向链表node
* @author chenfenli
*
*/
static class LinkNode {
// 数据
public Integer obj;
// 下一个结点
public LinkNode next;
public LinkNode(Integer obj) {
super();
this.obj = obj;
}
}
}
三、分析
- 案例思路:
- 对比A链表和B链表的头结点的值,确定为合并之后的头结点(小的为头结点)。
- 按大小对比,遍历剩下的A链表和B链表对比。
- 当至少有一个链表遍历到尾部,做最后一次next赋值。
- 结束
- 已常规:按顺序合并链表为列:
1.获取头结点:
2.遍历其它结点对比:
3.B链表遍历到尾部,没有下一个结点时,最后一次next