原题:
设线性表L=(a1,a2,a3,…an-2,an-1,an)采用带头结点的单链表保存,链表中的结点定义如下:
typedef struct node
{
int data;
struct node*next;
}NODE;
请设计一个空间复杂度为O(1)且时间上尽可能高效的算法,重新排列L中的各结点,得到线性表L’=(a1,an,a2,an-1,a3,an-2,…)
要求:
1)给出算法的基本设计思想
2)根据设计思想,采用C或者C++语言描述算法,关键之处给出注释。
3)说明你所设计的算法的时间复杂度
我的思考角度:
第一步:倘若要求的输出中没有a1,a2,a3…仅要求我们输出(an,an-1,an-2,…(最后一个点是中点)),那么这题就变成了一个倒置链表的题,我们要做的事只有两个:
1.找到这个中点
2.倒置这部分链表
第二步:考虑到这题要交叉输出a1,a2,a3,很容易想到这题便是找到链表中点,然后在中点处切割成两半,倒置后面一部分,然后交叉连接这两部分即可
第三步:上述的逻辑中需要用到两个基本的技巧
1.找到中点:快慢指针(维护两个指针,同时出发,一个一次跳一步,一个一次跳两步,快指针到达终点时慢指针到达中点)
2.倒置链表( 这个已经可以单独出题)
难点
1.交叉连接两个链表需要两个临时变量存链表下一个结点,以避免信息丢失
2.采用就地倒置链表(与头插法类似)的方式得出的倒转链表会导致最后一个结点(即原始链表的第一个有效结点)自环(即x->next=x)!注意单独判断
代码:
#include <iostream>
using namespace