题目:输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是按照递增排序的。例如输入 链表1 :1->3->5->7
链表2:2->4->6->8,则结果为1->2->3->4->5->6->7->8
这里我介绍两种写法,其实两种写法思路是一样的,只不过第二中解法将循环写成了递归,这样看起来漂亮的多,不过还是建议要把第一种弄懂这样会对我们的理解好的多。
首先,对于两个链表,我们需要进行参数检查
之后,写两个指针分别指向各自的第一个元素,新建一个链表,将两个指针对应的节点中较小的数加到新链表上,同时较小的数所在链表指针往后移一位,一直这样循环到某一链表遍历完毕为止。
现在我们完成了第一步,接下来需要判断,是否有某个链表还没有遍历完?(示例中的链表是等长的,但不是所有链表都是等长的)因为链表本身是有序的,因此我们直接将它续上去即可。
第一种解法代码如下:
private static Node combine(Node list , Node otherList){
if (list == null) {
return otherList;
}
if (otherList == null) {
return list;
}
//end:始终指向新链表的最后一个节点
Node end = new Node();
//minInP1AndP2:指向p1和p2中最小的一个
Node minInP1AndP2 = new Node();
//最终结果节点
Node result = end;
Node p1 = list;
Node p2 = otherList;
while(p1 != null && p2 != null){
if (p1.getNumber() <= p2.getNumber()) {
end.setNumber(p1.getNumber());
minInP1AndP2.setNumber(p2.getNumber());
}else{
end.setNumber(p2.getNumber());
minInP1AndP2.setNumber(p1.getNumber());
}
end.setNext(minInP1AndP2);
p1 = p1.getNext();
p2 = p2.getNext();
//若不加这个if判断会在最后出现一个new Node()
if (p1 != null || p2 != null) {
//将end指向新链表的最后一个节点
end = new Node();
minInP1AndP2.setNext(end);
minInP1AndP2 = new Node();
}
}
//若p2为null(p2已经结束,但p1还没有)
while(p1 != null){
end.setNumber(p1.getNumber());
if (p1.getNext() != null) {
//将end指向新链表的最后一个节点
minInP1AndP2 = new Node();
end.setNext(minInP1AndP2);
end = minInP1AndP2;
}
p1 = p1.getNext();
}
//若p1为null(p1已经结束,但p2还没有)
while(p2 != null){
end.setNumber(p2.getNumber());
if (p2.getNext() != null) {
//将end指向新链表的最后一个节点
minInP1AndP2 = new Node();
end.setNext(minInP1AndP2);
end = minInP1AndP2;
}
p2 = p2.getNext();
}
return result;
}
第二中思路其实和第一种完全一样,唯一不同的就是改变了写法,用递归代替while循环,这样看上去会好的多。(第二中里面开始的入口参数检查其实本身就包含了第一中方法中两个链表不一样长的解决方法)
private static Node combine2(Node list , Node otherList){
if (list == null) {
return otherList;
}
if (otherList == null) {
return list;
}
Node result = new Node();
if (list.getNumber() < otherList.getNumber()) {
result.setNumber(list.getNumber());
result.setNext(combine2(list.getNext(), otherList));
}else {
result.setNumber(otherList.getNumber());
result.setNext(combine(list, otherList.getNext()));
}
return result;
}
这里的Node是一个封装好的类:
class Node{
public Node(int n){
this.number = n;
}
public Node(){
this(0);
}
private int number;
private Node next;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public String toString() {
return "Node [number=" + number + "]";
}
}