前言:
链表是一种常见的数据结构,他是线性表的一种,他的典型特征就是数据结点之间通过指针相连,链表主要适合存储插入、删除操作比较频繁的数据。这篇文章总结如何合并两个有序链表。
题目原文
编程实现将两个有序的单链表LA(含有m个节点)和LB(含有n个节点)合并成一个新的有序单链表LA,原有单链表LA和LB中的结点都按数据域值以非递减排列。
题目解析
题目说的太绕,直白的说就是将链表LA、LB合并,合并后的链表依然使用LA来存储,且需要保证合并后的链表依然是有序的(m、n两个链表长度其实没啥用)。
思路分析
标识链表的唯一性的是链表的头结点(注意不是首结点),所以我们只需要将所有数据结点都合并到链表LA的头结点上即可,合并所有结点,就需要对两个链表的所有结点进行比较,将比较小的值进行从新排列组成一个新的有序链表。这里的核心要义是只将获取到的更小值所在的链表继续递归,比较结果较大的值应该继续参与下一次的比较。
代码实现
//合并两个单链表,且原先两个个链表的节点都是按照非递减排列(递增)
/**
* 思路:
* 核心思路:遍历两个链表,每次只将更小的值继续递归
*
* 为什么不使用返回:
* 不使用返回,是因为操作的都是同一个堆中对象,在调用的地方,原对象就改变了
* 无需返回再获取,原对象直接使用即可,写返回的话,仅仅是为了更好的理解而已
* @param LA
* @param LB
*/
public static void merge(NewLinkedTable LA, NewLinkedTable LB){
Node oneNode = LA.head.next;//获取LA的首结点
Node twoNode = LB.head.next;//获取LB的首结点
Node threeNode = LA.head;//准备用于拼接新的链表节点的头结点
int valueOne,valueTwo;//定义两个边量,用于接收两个链表中数据元素的数据域
while(oneNode!=null && twoNode!=null){//两个链表有一个遍历完成,立即退出循环,因为剩下的元素也是有序
valueOne = Integer.valueOf(oneNode.object.toString());
valueTwo = Integer.valueOf(twoNode.object.toString());
if(valueOne<=valueTwo){//若是LA元素更小
threeNode.next = oneNode;//将头结点指向当前元素
threeNode = threeNode.next;//更新待拼接元素的节点位置,将其指向最新的节点,等待下一次拼接
oneNode = oneNode.next;//当前元素已入新链表,将LA节点往下递归一位
}else{
threeNode.next = twoNode;
threeNode = threeNode.next;
twoNode = twoNode.next;
}
}
threeNode.next = (oneNode.next!=null?oneNode:twoNode);//当退出循环是LA、LB必定有一个是非null的,拼接非null的数据元素及其以后的结点元素
}
总结
这个题目解决的核心思路应该是:循环比较两个链表的元素,每次只递归获取到目标元素所在的链表,另一个链表不用递归,应继续参与下一轮的比较,其他具体细节的思路,在代码中都有注释。记录问题,记录成长,也希望可以帮到路过的你。