前言
王道2019统考真题
正文
题目
设链表L(a1,a2,a3,…,an-2,an-1,an)采用头结点的单链表保存
请设计一个空间复杂度为O(1)时间上尽可能高效的算法,重新排列L,得到线性表变成(a1,an,a2,an-1,a3,an-2,…)
关键
- 先找出链表L的中间点,为此设置了两个指针p和q,指针p每次走一步,q每次走两步,当指针q达到链尾时,指针p正好在链表的中间点
- 然后将L的后半部分原地逆置
- 从单链表前后两段中以此各取一个结点,按要求重排
这道题涉及了链表的双指针法,链表的逆置,链表的基本操作(头插等),值得自己慢慢消化
代码
void Change_list(Linklist h){
LNode *p,*q,*r,*s;
p=q=h;
/*双指针找链表的中点*/
while(q->next!=NULL){
p=p->next; //p走一步
q=q->next;
if(q->next!=NULL)q=q->next; //q走两步
}
/*链表的逆置*/
q=p->next; //p所指结点为中点
p->next=NULL; //q为后半链表的首结点
while(q!=NULL){
r=q->next;
q->next=p->next;
p->next=q;
q=r;
}
/*后半部分的链表头插进入前半部分*/
s=h->next;
q=p->next;
p->next=NULL;
while(q!=NULL){
r=q->next
q->next=s->next;//将q所指结点插入到s所指结点之后
s->next=q;
s=q->next; //将s指向前半段的下一个插入点
q=r;
}
}