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已经存在,不能加入
", 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

原文地址:https://www.cnblogs.com/kaka-qiqi/p/15132395.html