题目
先看题目,给定一个链表,奇数项为递增序列,偶数项为递减序列,如图:
要求将链表按从小到大进行排序。
这个题目看上去可能就是一个简单的链表,但是要怎么做到将链表按照升序的顺序进行排序。这里我们可以用三步,可能比较繁琐,但是经过这三步的过程,我们会对链表的一些常规操作有一个很清晰的认识和理解,这三个步骤就是:
- 链表拆分,先将整个链表拆为两个部分,升序子链表和降序子链表,也就是将下标为奇数和偶数的元素分别放到两个链表中
- 链表翻转,将下标为偶数链表元素组成的新的子链表进行翻转,使其按从小到大排列
- 链表合并,前面两个步骤得到了两个从小到大的链表,现在只需要将这两个链表进行合并
Node的定义(为了减少代码,用了lombok):
1 | less复制代码@Data |
链表拆分
这个过程比较简单,就按下标的奇偶性进行拆分就行了,代码如下:
1 | ini复制代码public static void main(String[] args) { |
head0.next和head1.next就是拆分出来的两个子链表了
输出结果如下:
链表翻转
翻转的过程主要的思想是使用双指针,一前一后两个指针来遍历链表并且改变next指针的方向,这里并没有另外创建一个新的链表来实现翻转,整个过程的流程如下动图,不明白的话,更详细的的步骤可以参考文末的参考文章。
有动图我就直接上代码了:
1 | ini复制代码private static Node reverse(Node head) { |
合并链表
力扣有一个剑指 Offer类似的题目可以参考一下:合并有序链表难度为简单。可以参考这一篇题解:题解
其实整个过程就是先遍历一个链表,遍历的时候和另一个链表当前的头结点的大小比较谁的值更小就取谁的值,然后将头结点指向下一个节点,如果另一个链表元素还有剩下的,说明都是比最后一个元素更大的,直接拼到后面就可以了,代码如下:
1 | ini复制代码private static Node merge(Node node0, Node node1){ |
完整代码
1 | ini复制代码public class ReSort { |
这种解法可能比较繁琐,代码量也比较多,但是思路很清晰,也涉及了多种链表的操作。
【参考】
【1】mp.weixin.qq.com/s/pnvVP-0ZM…
【2】力扣
本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
本文转载自: 掘金