![C#程序员面试算法宝典](https://wfqqreader-1252317822.image.myqcloud.com/cover/733/33643733/b_33643733.jpg)
上QQ阅读APP看书,第一时间看更新
1.7 如何把链表相邻元素翻转
难度系数:★★★☆☆ 被考察系数:★★★★☆
题目描述:
把链表相邻元素翻转,例如给定链表为 1->2->3->4->5->6->7,则翻转后的链表变为2->1->4->3->6->5->7。
分析与解答:
方法一:交换值法
最容易想到的方法就是交换相邻两个结点的数据域,这种方法由于不需要重新调整链表的结构,因此,比较容易实现,但是这种方法并不是考官所期望的解法。
方法二:就地逆序
主要思路:通过调整结点指针域的指向来直接调换相邻的两个结点。如果单链表恰好有偶数个结点,那么只需要将奇偶结点对调,如果链表有奇数个结点,那么除最后一结点外的其他结点进行奇偶对调。为了便于理解,下图给出了其中第一对结点对调的方法。
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_55_02.jpg?sign=1739217869-DhrJkssHwMK06RQwu3uM62WvGtU8tb14-0-5e0abdab5b0143a0d13acb826c328f1e)
在上图中,当前遍历到结点cur,通过(1)~(6)6个步骤用虚线的指针来代替实线的指针实现相邻结点的逆序。其中,步骤(1)~(4)实现了前两个结点的逆序操作,(5)和(6)两个步骤向后移动指针,接着可以采用同样的方式实现后面两个相邻结点的逆序操作。实现代码如下:
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_55_03.jpg?sign=1739217869-eiFsnveV9HvbS9NFROOUJ9d4M6GmqM9g-0-38b5286834ca26b5037a04de9cc63266)
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_56_01.jpg?sign=1739217869-l2l43Z3KQJ9EdkWKXuOaG3XWAuf1mSku-0-ed80fbaf46a0c3f98625cc464331054b)
程序的运行结果为
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_56_02.jpg?sign=1739217869-gKoEfJhlniu4PL6wLubd3NYGPqPBqK14-0-b8d838a8bbaa8f848a6a55f72233f22c)
上例中,由于链表有奇数个结点,因此,链表前三对结点相互交换,而最后一个结点保持在原来的位置。
算法性能分析:
这种方法只需要对链表进行一次遍历,因此,时间复杂度为O(n)。另外由于只需要几个指针变量来保存结点的地址信息,因此,空间复杂度为O(1)。