合并两个排序的链表的三种方法
1,使用数组解决
利用ArrayList<Integer>建立数组,存储链表中的数据,存储之后利用函数Collections.sort()将链表进行排序,排序之后数据是我们需要的顺序,之后建立新的链表把数据存储进来。
原理如图:
代码如下:
public ListNode Merge(ListNode pHead1,ListNode pHead2) {
//先检查list1 list2为空的情况
if(pHead1==null) return pHead2;
if(pHead2==null) return pHead1;
if(pHead1 == null && pHead2 == null){
return null;
}
//将两个两个链表存放在list中
ArrayList<Integer> list = new ArrayList<>();
//遍历链表pHead1,存储pHead1中的数据
while(pHead1!=null){
list.add(pHead1.val);
pHead1 = pHead1.next;
}
//遍历链表pHead2,存储pHead2中的数据
while(pHead2!=null){
list.add(pHead2.val);
pHead2 = pHead2.next;
}
//利用函数对数组list进行排序
Collections.sort(list);
//最后将list转换为新的链表newHead
ListNode newHead = new ListNode(list.get(0));
ListNode cur = newHead;
for(int i=1;i<list.size();i++){
cur.next = new ListNode(list.get(i));
cur = cur.next;
}
return newHead;
}
2,遍历
这个方法的本质就是遍历两个链表把小的数据拿出来,放入新的链表的节点
先设置newHead为新节点,放置于新链表之前,最后返回的就是newHead.next;按照顺序遍历两个链表,把小的数据存入新的链表中,然后更新链表。其中当任何一个节点为null的时候退出循环,记得最后把还没比较的数据都存入新链表中。
原理如下:
代码如下:
public ListNode Merge(ListNode pHead1, ListNode pHead2) {
// 先判断两个链表是否为空链表
if (pHead1 == null || pHead2 == null) {
return pHead1 != null ? pHead1 : pHead2;
}
// 建立新的链表来存储数据
ListNode newHead = new ListNode(-1);
// 保存newHead的地址,留着进行最后数据的返回
ListNode returnHead = newHead;
// 当其中任何一个节点为null时候退出循环比较
while (pHead1 != null && pHead2 != null) {
if (pHead1.val < pHead2.val) {
newHead.next = pHead1;
pHead1 = pHead1.next;
} else {
newHead.next = pHead2;
pHead2 = pHead2.next;
}
//每次比较完成之后更新新节点
newHead = newHead.next;
}
// 别忘了循环结束之后还需要拼接未对比的链表
newHead.next = pHead1 == null ? pHead2 : pHead1;
return returnHead.next;
}
3,递归
最后的,也是最难理解的方法就是递归,但是使用递归方法的逻辑很简洁。利用递归的特色,找到最终的节点。
利用递归找到最大的一个节点,在返回的过程中不断更新节点,使得前一个节点小于后一个节点。最后把整理好的节点进行返回。
原理图就不画了(抱歉,有点难画):
代码如下;
public ListNode Merge(ListNode pHead1, ListNode pHead2) {
//当其中一个链表已经为null的时候
//说明另一个链表中的数据一定为大的数据
//所以,返回另一个链表的数据
if (pHead1 == null || pHead2 == null) {
return pHead1 != null ? pHead1 : pHead2;
}
// 两个链表元素依次对比
if (pHead1.val < pHead2.val) {
// 递归计算
// 把小的数据作为前节点,用于接受大的返回值
pHead1.next = Merge(pHead1.next, pHead2);
// 返回当前节点,用于和前节点的拼接和最终的返回
return pHead1;
} else {
// 递归计算
pHead2.next = Merge(pHead1, pHead2.next);
return pHead2;
}
}
总的来说这个题目的难点比较低。
核心部分就是想办法建立新的链表,把原先两个链表的数据按照顺序接入新的链表当中。
加油尽可能的去使用递归来解决这道题目!!
加油同学!!!