有序链表合并
题目:已知两个链表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);
}
}