已知兩個連結串列head1和head2各自有序,請把它們合併一個依然有序的連結串列。結果連結串列要包含head1和head2的所有結點,即結點值相同。
阿新 • • 發佈:2022-01-02
本題可以採用遞迴法於非遞迴法兩種方式實現。以下將分別對這兩種方法進行分析。
方法一:遞迴法
具體步驟如下所示:
1)比較連結串列1(head1)和連結串列2(head2)的第一個結點資料,如果head1.data<head2.data,則把結果連結串列頭結點指向連結串列head1中的第一個結點。
2)對剩餘的連結串列head1.next和連結串列2(head2)再呼叫同樣的方法,比較得到結果連結串列的第二個結點,新增到合併列表的後面。
3)一直遞迴呼叫步驟2),直到兩個連結串列的結點都被加到結果連結串列中。
實現程式碼如下所示:
class Node{ Node next = null; int data; public Node(int data) { this.data = data; } } public class MergeTest { public static Node mergeList(Node head1,Node head2){ if (head1==null) { return head2; } if (head2==null) { return head1; } Node head = null; if (head1.data<head2.data) { head = head1; head.next = mergeList(head1.next,head2); }else { head = head2; head.next = mergeList(head1,head2.next); } return head; } public static void main(String[] args) { Node head1 = new Node(1); Node node3 = new Node(3); head1.next = node3; Node node5 = new Node(5); node3.next = node5; node5.next = null; Node head2 = new Node(2); Node node4 = new Node(4); head2.next = node4; Node node6 = new Node(6); node4.next = node6; node6.next = null; Node mergeHead = mergeList(head1,head2); while (mergeHead!=null) { System.out.print(mergeHead.data + " "); mergeHead = mergeHead.next; } } }
方法二:非遞迴法
在遍歷兩個連結串列的過程中,改變當前連結串列指標的指向來把兩個連結串列串聯程一個有序的列表,實現程式碼如下:
public static Node mergeList2(Node head1,Node head2){ if (head1==null) { return head2; } if (head2==null) { return head1; } Node p1,p2,head; //確定合併後的頭結點 if(head1.data<head2.data){ head = head1; p1 = head1.next; p2 = head2; } else { head = head2; p1 = head1; p2 = head2.next; } Node pcur = head; while (p1 != null && p2 != null) { //把連結串列head1當前遍歷的結點新增到合併後連結串列的尾部 if (p1.data<=p2.data) { pcur.next = p1; pcur = p1; p1 = p1.next; } //把連結串列head2當前遍歷的結點新增到合併連結串列的尾部 else { pcur.next = p2; pcur = p2; p2 = p2.next; } //head2連結串列已經遍歷結束,把head1遍歷剩餘的結點新增到合併後連結串列的尾部 if (p1!=null) { pcur.next = p1; } if (p2!=null) { pcur.next = p2; } } return head; }