有序链表合并
题目:已知两个链表head1和head2各自有序,请把它们合并成一个链表依然有序。结果链表要包含head1和head2的所有节点,即使节点值相同。
分析:此题目使用链表结构,目的是为了让答题者不增加额外的存储空间来实现,所以不能把值全拿出来排序再放回链表。而由于链表本身有序,所以可以分别比较两个链表对应的值,较小者取之,其所在的链表往后推一位(升序排),直至某链表遍历完成,将另一链表剩余添加到尾部。使用递归实现会更加简单。
java循环结构实现:
public static Node merge(Node a, Node b) { if (a == null) return b; if (b == null) return a; Node head, tmpa, tmpb; if (a.value < b.value) { head = a; tmpa = a.next; tmpb = b; } else { head = b; tmpb = b.next; tmpa = a; } Node tmp = head; while (tmpa != null && tmpb != null) { if (tmpa.value < tmpb.value) { tmp.next = tmpa; tmp = tmpa; tmpa = tmpa.next; } else { tmp.next = tmpb; tmp = tmpb; tmpb = tmpb.next; } } tmp.next = (tmpa == null) ? tmpb : tmpa; return head; }
java递归实现
public static Node merge_rec(Node a, Node b) { if (a == null && b == null) { return null; } else if (a == null) { return b; } else if (b == null) { return a; } Node result = null; if (a.value <= b.value) { result = a; result.next = merge(a.next, b); } else { result = b; result.next = merge(b.next, a); } return result; }
有序数组合并
同样,合并两个有序的数组可以采用类似的方法。
public class ArrayMerge { public static int[] merge(int[] a, int[] b) { int[] result = new int[a.length + b.length]; int i, j, k; i = 0; j = 0; k = 0; while (i < a.length && j < b.length) { if (a[i] < b[j]) { result[k++] = a[i]; i++; } else { result[k++] = b[j]; j++; } } while (i < a.length) { // a有剩余 result[k++] = a[i]; i++; } while (j < b.length) { // b有剩余 result[k++] = b[j]; j++; } return result; } public static void print(int[] a) { for (int e : a) { System.out.print(e + "\t"); } System.out.println(); } public static void main(String[] args) { int[] a = { 1, 2, 8, 19 }; int[] b = { 2, 3, 9, 12, 25 }; int[] c = merge(a, b); print(c); } }