分析過程
將兩個有序的單鏈表合並成一個有序的單鏈表,本人的思路是利用第三個單鏈表存儲兩個單鏈表的節點,若兩個鏈表均為空,則直接返回;若其中一個鏈表為空,則直接將另一個鏈表連接至鏈表3上;若兩個鏈表均不為空,先將其中一個鏈表1連接至鏈表3,然后遍歷另一個鏈表2,將鏈表2中的節點按照順序連接至鏈表3上。若出現鏈表3遍歷完畢但鏈表2尚未遍歷完畢的情況,可以直接將鏈表2剩下的節點連接至鏈表3尾部。
代碼實現
public class TwoLinkedListDemo {
public static void main(String[] args) {
// 創建節點
Node node1 = new Node(1, "大娃");
Node node2 = new Node(2, "二娃");
Node node3 = new Node(3, "三娃");
Node node4 = new Node(4, "四娃");
Node node5 = new Node(5, "五娃");
Node node6 = new Node(6, "六娃");
Node node7 = new Node(7, "七娃");
Node node8 = new Node(8, "葫蘆小金剛");
// 創建鏈表
SingleLinkedList singleLinkedList1 = new SingleLinkedList();
SingleLinkedList singleLinkedList2 = new SingleLinkedList();
SingleLinkedList singleLinkedList3 = new SingleLinkedList();
// 添加節點
singleLinkedList1.addByOrder(node1);
singleLinkedList1.addByOrder(node3);
singleLinkedList1.addByOrder(node6);
singleLinkedList1.addByOrder(node7);
singleLinkedList2.addByOrder(node2);
singleLinkedList2.addByOrder(node4);
singleLinkedList2.addByOrder(node5);
singleLinkedList2.addByOrder(node8);
// 顯示兩個鏈表
System.out.println("單鏈表1:");
singleLinkedList1.list();
System.out.println("單鏈表2:");
singleLinkedList2.list();
// 顯示合並后的鏈表
twoLinkedList(singleLinkedList1.getHead(), singleLinkedList2.getHead(), singleLinkedList3.getHead());
System.out.println("組合后的鏈表:");
singleLinkedList3.list();
}
// twoLinkedList方法
// 傳入待合並的兩個鏈表的頭節點以及第三個單鏈表的頭節點
public static void twoLinkedList(Node head1, Node head2, Node head3) {
// 如果兩個鏈表均為空,則無需合並,直接返回
if(head1.next == null && head2.next == null) {
return;
}
// 如果鏈表1為空,則將head3.next指向head2.next,實現鏈表2中的節點連接到鏈表3
if(head1.next == null) {
head3.next = head2.next;
} else if(head2.next == null){
head3.next = head1.next;
} else {
// 將head3.next指向head1.next,實現鏈表1中的節點連接到鏈表3
head3.next = head1.next;
// 定義一個輔助的指針(變量),幫助我們遍歷鏈表2
Node cur2 = head2.next;
// 定義一個輔助的指針(變量),幫助我們遍歷鏈表3
Node cur3 = head3;
Node next = null;
// 遍歷鏈表2,將其節點按順序連接至鏈表3
while(cur2 != null) {
// 鏈表3遍歷完畢后,可以直接將鏈表2剩下的節點連接至鏈表3的末尾
if(cur3.next == null) {
cur3.next = cur2;
break;
}
// 在鏈表3中,找到第一個大於鏈表2中的節點編號的節點
// 因為是單鏈表,找到的節點是位於添加位置的前一個節點,否則無法插入
if(cur2.no <= cur3.next.no) {
next = cur2.next; // 先暫時保存鏈表2中當前節點的下一個節點,方便后續使用
cur2.next = cur3.next; // 將cur2的下一個節點指向cur3的下一個節點
cur3.next = cur2; // 將cur2連接到鏈表3上
cur2 = next; // 讓cur2后移
}
// 遍歷鏈表3
cur3 = cur3.next;
}
}
}
}
//定義SingleLinkedList類,管理節點
class SingleLinkedList {
// 先初始化頭節點,頭節點不動
private Node head = new Node(0, "");
// 獲取鏈表的頭節點
public Node getHead() {
return head;
}
// 添加節點時,根據編號按順序將節點插入到指定位置
// 如果鏈表中已有這個編號,則添加失敗,並給出提示
public void addByOrder(Node node) {
// 頭節點不能動,通過一個輔助指針(變量)幫助找到需要添加的位置
// 因為是單鏈表,找到的temp是位於添加位置的前一個節點,否則無法插入
Node temp = head;
boolean flag = false; // flag標志添加的編號是否存在,默認為false
while(true) {
if(temp.next == null) {
break;
}
if(temp.next.no > node.no) {
break;
}
if(temp.next.no == node.no) {
flag = true;
break;
}
temp = temp.next; // 遍歷鏈表
}
if(flag) {
System.out.printf("輸入的編號%d已經存在,不能加入\n", node.no);
}
else {
node.next = temp.next;
temp.next = node;
}
}
// 顯示鏈表【遍歷】
public void list() {
// 判斷鏈表是否為空
if(head.next == null) {
System.out.println("鏈表為空");
return;
}
// 因為頭節點不能動,需要一個輔助變量來遍歷
Node temp = head.next;
while (true) {
// 判斷是否到鏈表最后
if(temp == null)
break;
// 輸出節點的信息
System.out.println(temp);
// 將temp后移
temp = temp.next;
}
}
}
//Node類,每個Node對象就是一個節點
class Node {
public int no;
public String name;
public Node next; // 指向下一個節點
// 構造器
public Node(int no, String name) {
this.no = no;
this.name = name;
}
// 為了顯示方便,重新toString
@Override
public String toString() {
return "Node [no=" + no + ", name=" + name + "]";
}
}
結果
畫圖展示