题目描述:将链表L(a1,a2,a3,...,an-2,an-1,an)重排为L'(a1,an,a2,an-1,a3,an-2,...),要求空间复杂度为O(1)。
算法描述:
一、先找到L的中心节点,设置两个指针p和q。p一次走一步,q一次走两步,当q走到末尾时,
1.当链表长为奇数时,p走到中心节点。
2.当链表长为偶数时,观察可知需要重新插入的节点是中间两个节点的后一个的后面节点,如:123456,此时需要重新插入的节点是5和6,此时p走到中间两个节点的后一个节点。
二、将需要重新插入的后一段节点逆置,即无论是奇数还是偶数都是从p的下一个节点开始逆置。
三、从后一段依次拿出节点插入前一段。
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;//单链表
void change_list(LinkList L){
LNode *p,*q,*r,*s;
p=q=L;
while(q->next!=NULL){ //找到逆置点的前一个节点
p=p->next;
q=q->next;
if(q->next!=NULL) q=q->next;
}
q=p->next;
p->next=NULL; //后一段逆置后的L的末尾
while(q!=NULL){ //后一段用头插法逆置
r=q->next;
q->next=p->next;
p->next=q;
q=q->next;
}
s=L->next; //s为前一段起始点
q=p->next;
p->next=NULL; //重排后的末尾
while(q!=NULL){ //依次插入
r=q->next;
q->next=s->next;
s->next=q;
s=q;
q=r;
}
}