当前位置: 首页 > 编程笔记 >

逆转交替合并两个链表的解析与实现

慕高阳
2023-03-14
本文向大家介绍逆转交替合并两个链表的解析与实现,包括了逆转交替合并两个链表的解析与实现的使用技巧和注意事项,需要的朋友参考一下

逆转交替合并两个链表,即从一个链表的尾指针指向另一个链表的尾指针,依次逆转交替进行合并。下面就通过实例来详细的介绍该逆转交替合并两个链表的思路与实现代码。

一、问题描述

链表A和B
A: 1->2->3->4
B: a->b->c->d
请逆转交替合并两个链表,示例结果如下:
4->d->3->c->2->b->1->a
节点类型定义如下:

classNode {
 public Node next;
 ...
}

二、源代码:

传入两个A和B链表,返回处理后的链表:


Node reverse_merge(Node A, Node B) 
{ 
 //A、B都只有一个节点 
 if(A.next==null) 
 { 
 A.next=B; 
 return A; 
 } 
 //A、B都大于等于2个节点 
 Node nextA; 
 Node nextB; 
 
 nextB = B.next; 
 B.next = null; 
 nextA = A.next; 
 A.next = B; 
 B = nextB; 
 while (nextA.next != null) 
 { 
 B.next = A; 
 A = nextA; 
 nextA = A.next; 
 A.next = B; 
 B = nextB; 
 } 
 nextB.next = A; 
 nextA.next = B; 
 return nextA; 
} 

三、解析:

程序分成三个部分——while循环之前、while循环体、while循环之后。
1)处理之前的链表A和B


2)while循环——核心的处理部分
这里处理程序的可重复的部分,我们的目标是红色的部分,要达成红色的链接模式,有两个原子结构:深红色圆圈1和蓝色圆圈2


但是1中需要特别处理a所在的节点,仅对于a所在的节点需要一个next=null的操作,也就是说1中的第一个原子要放在循环之外实现,这包括1指向a,b指向1的操作。

换种方式,如果使用2方式,就只需要将1指向a放在循环之外。所以,这里采用了2中描述的原子结构。

原子结构需要的信息

当我们进行到某一次循环时,假设进行到蓝色圆圈的操作了,这时候我们链表的状态为:


更为直观的画法为:


它涉及到3个节点——2,3和c。其中红色部分是我们希望做到的链接方式。为了链接c->2,3->c,必须知道有相应的指针记录他们的位置。所以在循环之前我们需要掌握这三个元素的地址,并且在处理完之后,用相同的方式表示下一次需要处理的原子结构。

例如以下这种方式记录这次循环中设计的3个节点的地址:


A、nA、B代表指向相应节点的指针或者说是引用。

在处理完成之后需要用相同的方式记录下一次原子结构涉及的节点,这样才能保证循环能够按统一逻辑执行下去,我们的目标是:


这些赋值操作正是循环体的中代码所做的事情,恰好代码也是按照上面指定的命名形式,有一点区别,图中的nA代表代码中的nextA。除此之外,代码中定义了nextB作为一个中间变量,用来记录c->d断开之前d节点的地址,因为c指向2之后就会失去对d的联系,这个中间变量是必须的。

3)while循环之前——解决预备操作所带来的问题

我们还没有处理a节点,因为它太特殊了,没有合适的原子结构能包括它。所以我们把它放在循环体之外,并且为循环做好准备工作,我们希望的结果是这样:


在这之后我们就可以把1,2,b放在循环体中处理。这里也考虑了A、B都只有一个节点的情况,也需要单独处理。

4)while循环之后——最后的处理

当我们发现B链表到达末尾时,结束循环。但这时候并有处理末尾节点,换句话说,末尾节点不在原子结构中。我们的循环会停止在这个原子结构中:


作为最后的操作,我们需要手动处理d->3,4->d的链接步骤——这也是没有办法的,因为原子结构的处理必须找到能够把所有指针传递下去的节点,作为最后的节点是没办法吧指针继续传递下去。

这不是一个完整的方法,还有很多事情没有处理,比如输入的A、B如果不等长,应该如何处理。另外Node数据结构并没有完整的定义,不过这都不是本文讨论的重点。

通过以上详细的解析,希望能够帮助大家很好的理解该逆转交替合并两个链表的方法与实现。

 类似资料:
  • 21. Merge Two Sorted Lists 问题 Merge two sorted linked lists and return it as a new list. 思路 这个题目很简单也有几个可以考虑的思路,一个是比较直接的方式,重新构造链表,一种是利用递归 思路1 :用新的链表 这里用了一个新的节点了保存结果的链表,这里为了方便链表的扩充,增加一个临时的节点变量(否则每次加入都要遍

  • 本文向大家介绍python实现合并两个排序的链表,包括了python实现合并两个排序的链表的使用技巧和注意事项,需要的朋友参考一下 剑指offer:合并两个排序的链表,Python实现 题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 吐槽 本来想用递归实现,但是大脑卡壳,没有想到合适的递归策略,潜意识里还是把两个链表当成两个数组来看待,写出了

  • 本文向大家介绍c语言实现两个单链表的交叉合并方式,包括了c语言实现两个单链表的交叉合并方式的使用技巧和注意事项,需要的朋友参考一下 如下所示: 总结:链表的遍历注意不要随意改变头指针的位置,进行合并时需要声明三个结构体指针用于进行合并,注意某一链表结束时需要进行链接,再释放生成的链表. 以上这篇c语言实现两个单链表的交叉合并方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支

  • NowCoder 题目描述 解题思路 递归 // java public ListNode Merge(ListNode list1, ListNode list2) { if (list1 == null) return list2; if (list2 == null) return list1; if (list1.val <= lis

  • 假设列表“A”是1- 请回顾一下这个,帮我即兴创作

  • 给定两个已排序的链表,其中的结果应为并集,不重复。 不允许创建新节点 输入是两个由空行分隔的列表: L1级- L2级- 结果- 下面是我的解决方案,但在Union函数中创建新节点。 有没有什么简单的方法可以通过不创建任何新节点并删除重复节点的逻辑来更改Union函数?