JAVA合並兩個有序的單鏈表,合並之后的鏈表依然有序


分析過程

將兩個有序的單鏈表合並成一個有序的單鏈表,本人的思路是利用第三個單鏈表存儲兩個單鏈表的節點,若兩個鏈表均為空,則直接返回;若其中一個鏈表為空,則直接將另一個鏈表連接至鏈表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 + "]";
	}
}

結果

image

畫圖展示

image
image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM