剑指Offer系列(16)——合并两个排序的链表

本文介绍了一种合并两个递增排序链表的方法,通过迭代和递归两种方式实现新链表的构建,保持节点递增排序。文章详细解释了每种方法的步骤,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是按照递增排序的。例如输入 链表1 :1->3->5->7

链表2:2->4->6->8,则结果为1->2->3->4->5->6->7->8

 

这里我介绍两种写法,其实两种写法思路是一样的,只不过第二中解法将循环写成了递归,这样看起来漂亮的多,不过还是建议要把第一种弄懂这样会对我们的理解好的多。

首先,对于两个链表,我们需要进行参数检查

之后,写两个指针分别指向各自的第一个元素,新建一个链表,将两个指针对应的节点中较小的数加到新链表上,同时较小的数所在链表指针往后移一位,一直这样循环到某一链表遍历完毕为止。

现在我们完成了第一步,接下来需要判断,是否有某个链表还没有遍历完?(示例中的链表是等长的,但不是所有链表都是等长的)因为链表本身是有序的,因此我们直接将它续上去即可。

第一种解法代码如下:
 

private static Node combine(Node list , Node otherList){
		if (list == null) {
			return otherList;
		}
		if (otherList == null) {
			return list;
		}
		//end:始终指向新链表的最后一个节点
		Node end = new Node();
		//minInP1AndP2:指向p1和p2中最小的一个
		Node minInP1AndP2 = new Node();
		//最终结果节点
		Node result = end;
		
		Node p1 = list;
		Node p2 = otherList;
		
		while(p1 != null && p2 != null){			
			if (p1.getNumber() <= p2.getNumber()) {	
				end.setNumber(p1.getNumber());
				minInP1AndP2.setNumber(p2.getNumber());				
			}else{
				end.setNumber(p2.getNumber());
				minInP1AndP2.setNumber(p1.getNumber());		
			}
			
			end.setNext(minInP1AndP2);
			
			p1 = p1.getNext();
			p2 = p2.getNext();
			
			//若不加这个if判断会在最后出现一个new Node()
			if (p1 != null || p2 != null) {	
				//将end指向新链表的最后一个节点
				end = new Node();
				minInP1AndP2.setNext(end);
				minInP1AndP2 = new Node();
			}
			
			
		}
		
		//若p2为null(p2已经结束,但p1还没有)
		while(p1 != null){
			end.setNumber(p1.getNumber());
			if (p1.getNext() != null) {
				//将end指向新链表的最后一个节点
				minInP1AndP2 = new Node();
				end.setNext(minInP1AndP2);
				end = minInP1AndP2;
			}
			p1 = p1.getNext();
		}
		
		//若p1为null(p1已经结束,但p2还没有)
		while(p2 != null){
			end.setNumber(p2.getNumber());
			if (p2.getNext() != null) {
				//将end指向新链表的最后一个节点
				minInP1AndP2 = new Node();
				end.setNext(minInP1AndP2);
				end = minInP1AndP2;
			}
			
			p2 = p2.getNext();
		}
		
		return result;
		
	}

第二中思路其实和第一种完全一样,唯一不同的就是改变了写法,用递归代替while循环,这样看上去会好的多。(第二中里面开始的入口参数检查其实本身就包含了第一中方法中两个链表不一样长的解决方法)


	private static Node combine2(Node list , Node otherList){
		if (list == null) {
			return otherList;
		}
		if (otherList == null) {
			return list;
		}
		Node result = new Node();
		if (list.getNumber() < otherList.getNumber()) {
			result.setNumber(list.getNumber());
			result.setNext(combine2(list.getNext(), otherList));
		}else {
			result.setNumber(otherList.getNumber());
			result.setNext(combine(list, otherList.getNext()));
		}
		
		
		return result;
	}

 

这里的Node是一个封装好的类:

class Node{
	public Node(int n){
		this.number = n;
	}
	public Node(){
		this(0);
	}
	private int number;
	private Node next;
	
	public int getNumber() {
		return number;
	}
	public void setNumber(int number) {
		this.number = number;
	}
	public Node getNext() {
		return next;
	}
	public void setNext(Node next) {
		this.next = next;
	}
	@Override
	public String toString() {
		return "Node [number=" + number + "]";
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值