有如下有序链表 n1, n2:
1 -> 5 -> 9
1 -> 3 -> 6 -> 10
要求对链表进行合并,合并后的新链表依然有序:
1 -> 1 -> 3 -> 5 -> 6 -> 9 -> 10
由于链表是有序的,因此在遍历 n1, n2 的过程中,只需比较出两个链表较小的节点,将该节点追加在新链表末尾即可。比较步骤分解如下:
经过上述分析,可以得出解题步骤:
代码实现如下:
/** * 合并两个有序链表,合并后的链表依然有序 * * @param n1 * @param n2 * @return */ public static Node mergeSortedLinkedList(Node n1, Node n2) { if (n1 == null && n2 == null) { throw new RuntimeException("n1, n2 不能都为空"); } if (n1 == null) { return n2; } if (n2 == null) { return n1; } //创建空的头节点 Node head = new Node(); //创建临时引用,用于追加节点 Node tmp = head; do { if (n1.num <= n2.num) { //若 n1 小,则追加 n1,同时 n1 后移 tmp.next = n1; n1 = n1.next; } else { //若 n2 小,则追加 n2,同时 n2 后移 tmp.next = n2; n2 = n2.next; } //追加节点后,tmp 后移 tmp = tmp.next; //当 n1, n2 均不为空时,继续比较 } while (n1 != null && n2 != null); if (n1 == null) { //若 n1 为空,则追加 n2 整体 tmp.next = n2; } else { //若 n2 为空,则追加 n1 整体 tmp.next = n1; } //置空 tmp,便于垃圾回收 tmp = null; //返回新链表的起始引用 return head.next; }
有如下测试代码:
// 创建链表:1 -> 5 -> 9 Node n1 = new Node(1); n1.next = new Node(5); n1.next.next = new Node(9); //创建链表:1 -> 3 -> 6 -> 10 Node n2 = new Node(1); n2.next = new Node(3); n2.next.next = new Node(6); n2.next.next.next = new Node(10); //合并有序链表 n1, n2 Node head = mergeSortedLinkedList(n1, n2); System.out.println("n1: " + show(n1)); System.out.println("n2: " + show(n2)); System.out.println("合并后的链表:" + show(head));
输出如下:
n1: [Node{num=1}, Node{num=5}, Node{num=9}] n2: [Node{num=1}, Node{num=3}, Node{num=6}, Node{num=10}] 合并后的链表: [Node{num=1}, Node{num=1}, Node{num=3}, Node{num=5}, Node{num=6}, Node{num=9}, Node{num=10}]
结果如预期。