本人真的很菜qwq,大二学数据结构的时候链表逆置就一直弄不懂,今天死磕了一下午,找了各种讲解,终于弄懂了,话不多说嘞,上题!
5.设线性表 L=(a1,a2,a…,an-2,a-1,a。)采用带头结点的单链表保存,链表中结点定义如下:
请设计一个空间复杂度为 O(1)且时间上尽可能高效的算法,重新排列 L 中的各结点,得到线性表
L'=(a1,an,a2,an-1,a3,an-2…)。要求:
1.给出算法的基本设计思想
2.根据设计思想,采用 C 或 C++语言描述算法,关键之处给出注释。
3.说明你所设计的算法的时间复杂度。
L'相比于L是将最后一个元素插入到第一个元素之后,倒数第二个元素插入到第二个元素之后...
把整个表分为前后两部分,后半部分倒置,(带头结点的倒置链表问题)倒置后从前后两部分分别取一个元素出来进行排列放置
设置两个指针p和q,指针p每次走一步,指针q走两步,这样q走到表尾,p正好在表中间,然后将L的后半段结点原地逆置,从单链表前后两端中各取一个节点,重新排列
void change_link(NODE *h)
{
NODE *p,*q,*r,*s;
p=q=h;//初始都在一个位置上
while(q->next!=NULL){
p=p->next;//p走一步
q=q->next;//q走一步
if(q->next!=NULL)//判断下一步不会到队尾 q走两步
q=q->next
}
//循环结束之后,p指向链表的中间位置,对链表进行逆置
q=p->next;
p->next=NULL;//断链,让p和q之间断开
while(q!=NULL)
{
r=q->next;//用r存储q的下一个结点值防止断链时造成数据混乱
q->next=p->next;//q下一个结点的位置指向p下一个结点位置
p->next=q;//让q成为p的下一位
q=r;//q往后移动一位
}
s=h->next;//s指向前半段的第一个数据节点,即插入点
q=p->next;//q指向后半段的第一个结点
p->next=NULL;//断链
while(q!=NULL)
{
r=q->next;
q->next=s->next;
s->next=q;
s=q->next;
q=r;
}
}
废话一句 诶嘿进最佳新人了乐(利韩厨走遍世界篇)
回归正题
下面是对链表逆置的详解
此处特别感谢b站up小熊学长x,我的救命恩人,好多道题都是他讲懂的,包括前面那个辅助数组,对于我这种菜鸟真的很友好!图源讲解视频
断链操作就是让p->next=NULL,也就是在4和5中间是NULL,是断开的,m指向5,n指向6
m=p->next;
n=m->next;
m->next=p->next;//看图让m的next指向p的next,也就是5->NULL
p->next=m;//这句话是让p的下一个指向m也就是5,重新连接链式结构,此时的结构也就是p->5->NULL
m=n;//让m后移一个位置到n的位置,此时m指向6,n指向7
下一次循环,m->next=p->next;此时m指向6,p->next是5,也就是让6->5实现逆置
p->next=m;p的下一个指向m,此时的结构就变成了4->6->5,实现了倒置
ok这样是不是豁然开朗!单链表逆置拿下!