/**
*
* 问题:合并两个有序的单链表
* 给定两个有序单链表的头节点 head1和head2, 请合并两个有序链表, 合并后的链表依然有序,
* 并返回合并后链表的头节点。
* 例如:
* 0->2->3->7->null
* 1->3->5->7->9->null
* 合并后的链表为: 0-> 1->2->3->3->5->7->7->9->null
*
* 解答:
* 1.如果两个链表中有一个为空,说明无须合并过程, 返回另一个链表的头节点即可。
*
* 2.比较head1和 head2的值, 小的节点也是合并后链表的最小节点 这个节点无疑应该是合并链表的头
* 节点,记为 head; 在之后的步骤里, 哪个链表的头节点的值更小, 另一个链表的所有节点都会依次插
* 入到这个链表中。
*
* 3.不妨设 head节点所在的链表为链表 1,另一个链表为链表 2。链表 1和链表 2都从头部开始一起遍历,
* 比较每次遍历到的两个节点的值, 记为 cur1和cur2, 然后根据大小关系做出不同的调整,同时用一个
* 变量pre表示上次比较时值较小的节点。
*
* 例如, 链表1为 1->5->6->null ,
* 链表 2为 2->3->7->null。
*
* cur1=1,cur2=2, pre=null。cur1小于cur2, 不做调整, 因为此时 cur1较小,所以令
* pre=cur1=1,然后继续遍历链表 1的下一个节点, 也就是节点5。
* cur1=5,cur2=2, pre=1。cur2小于cur1,让 pre的 next指针指向 cur2,cur2的next
* 指针指向 cur1。这样,cur2便插入到链表 1中。因为此时 cur2较小,所以令 pre=cur2=2,然后继续
* 遍历链表 2的下一个节点, 也就是节点 3。这一步完成后, 链表1变为 1->2->5->6->null,链表2变为3->7->null。
* cur1=5, cur2=3, pre=2。cur1=5,cur2=3, pre=2。此时又是cur2较小,与上一步调
* 整类似, 这一步完成后, 链表1变为1->2->3->5->6->null,链表2为7->null。
* cur1=5, cur2=7, pre=3。cur1=5, cur2=7, pre=3。cur1小于cur2,不做调整,因
* 为此时cur1较小, 所以令pre=cur1=5, 然后继续遍历链表1的下一个节点,也就是节 点6。
* cur1=6, cur2=7, pre=5。cur1小于cur2, 不做调整, 因为此时cur1较小,所以令pre=cur1=6,
* 此时已经走到链表1的最后一个节点, 再往下就结束, 如果链表1或链表2有任何一个走到了结束, 就进入步骤4。
*
* 4.如果链表 1先走完, 此时cur1=null, pre为链表 1的最后一个节点, 那么就把 pre的 next指针指向链表2
* 当前的节点(即cur2), 表示把链表2没遍历到的有序部分直接拼接到最后, 调整结束。如果链表2先走完, 说明链
* 表2的所有节点都已经插入到链表l中,调整结束。
*
* 5. 返回合并后链表的头节点head。
*
* @author 雪瞳
*
*/
public class Node {
public int value;
public Node next;
public Node(int data){
this.value=data;
}
}
public class MergeNode {
public Node mergeNode(Node head1,Node head2){
if(head1 == null || head2 == null){
return head1 == null?head2:head1;
}
Node head = head1.value<head2.value?head1:head2;
// current 1 存储的是较小的元素
// current 2 存储的是较大的元素
Node current1 = head == head1 ? head1:head2;
Node current2 = head == head1 ? head2:head1;
// 存放当前current1和current2中最小的元素
Node preCurrent = null;
Node nextCurrent = null;
while(current1 != null && current2 != null){
if(current1.value <= current2.value){
// 1 < 2 继续遍历直到出现 2 < 1 的情况
preCurrent = current1;
current1 = current1.next;
}else{
// 1 > 2 将节点2的当前元素插入到 1 中
nextCurrent = current2.next;
preCurrent.next = current2;
current2.next = current1;
preCurrent = current2;
current2 = nextCurrent;
}
}
preCurrent.next = current1==null?current2:current1;
return head;
}
}
public class TestMergeNode {
public static void main(String[] args) {
TestMergeNode test = new TestMergeNode();
MergeNode merge = new MergeNode();
Node n1 = new Node(1);
Node n2 = new Node(2);
Node n3 = new Node(3);
Node n4 = new Node(4);
Node n5 = new Node(5);
Node n6 = new Node(6);
Node n7 = new Node(7);
Node n8 = new Node(8);
Node n9 = new Node(9);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
Node head1 = n1;
n6.next=n7;
n7.next=n8;
n8.next=n9;
Node head2 = n6;
test.showNodeList(head1);
test.showNodeList(head2);
Node result = merge.mergeNode(head1, head2);
test.showNodeList(result);
}
/*获取链表
public Node getNodeList(int length){
Random rand = new Random();
Node nodeArray[]= new Node[length];
for(int i=0;i<length;i++){
nodeArray[i]=new Node(rand.nextInt(10));
}
for(int i=0;i<length-1;i++){
nodeArray[i].next = nodeArray[i+1];
}
return nodeArray[0];
}*/
//显示列表元素
public void showNodeList(Node head){
Node current = null;
current = head;
System.out.println("链表元素如下...");
while(current!=null){
System.out.print(current.value+" ");
current=current.next;
}
System.out.println();
}
}