Java將兩個有序連結串列合併為一個有序連結串列、將兩個有序數組合併成一個有序陣列
阿新 • • 發佈:2019-01-01
有序連結串列合併
題目:已知兩個連結串列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);
}
}