2024王道408数据结构 P39 T25
思考过程
- 首先还是看题,我们举个例子,链表长下面这个样子
要我们变成第二行那样中间隔开排列,后面那一半要反着插。其中的1 2 3 4顺序没有变,只是中间插入了而已,但是后面的5 6 7 8是逆置了。所以我们首先要把后半个链表逆置一下。 - 要逆置后半个链表那我们就要先找出链表中间的那个结点,所以我们需要两个指针p和q,
让q指针每次往后移动2步q=q->next->next;
指针p就让他每次往后移动1个,p=p->next;
当q指针移动到元素8的时候,p正好走了4步到了元素4,p指针指向的就是中间的结点
这时候我们就要将后半部分的链表进行逆置变成8 7 6 5。 - 逆置呢就很简单把
q=p->next
,然后把p的后面置空p->next = NULL;
然后我们就用头插法开始逆置,过程就如下,这里就不多说了,目的就是让链表的后半部分逆置,让链表变成1 2 3 4 8 7 6 5这样 - 那我们把链表后半部分逆置完后就要开始插入了,我们建立一个新指针l用来指向第一个结点
l=L->next;
同时把q赋值q=p->next;p->next=NULL;
把p->next再次置空,用一个指针r来防止断链
这样就把8插入到1和2的中间了,插入之后移动l指针l=q->next;最后让q=r;
这样一次插入就完成了。
红笔为移动过后的。这样题目就写完了。
完整代码如下
//
// Created by 黎圣 on 2023/7/29.
//
#include "iostream"
typedef struct node
{
int data;
struct node *next;
}node, *linklist;
//我举的例子
int a[8] = {1,2,3,4,5,6,7,8};
int n = 8;
//创建链表
void CreateList(linklist &L)
{
L = (linklist)malloc(sizeof(node));
node *s, *r = L;
for (int i = 0; i < n; i++)
{
s = (linklist)malloc(sizeof(node));
s->data = a[i];
r->next = s;
r = r->next;
}
r->next = NULL;
}
//打印出来方便观察
void display(linklist L)
{
node *s = L->next;
while (s)
{
printf("%d ", s->data);
s = s->next;
}
printf("\n");
}
//题目主代码
void newlist(linklist &L)
{
node *p = L, *q = L, *l, *r;
while (q->next != NULL)
{
p = p->next;
q = q->next;
if (q->next != NULL) q = q->next;
}//让p找到中点
//逆置
q = p->next;
p->next = NULL;
while (q)
{
r = q->next;
q->next = p->next;
p->next = q;
q = r;
}
//开始插入
q = p->next;
l = L->next;
p->next = NULL;
while (q)
{
r = q->next;//防止断链
q->next = l->next;
l->next = q;
l = q->next;
q = r;
}
}
int main()
{
linklist L;
CreateList(L);
display(L);
newlist(L);
display(L);
return 0;
}
这题我干了一个小时…对我来说确实是有.难,最后感谢b站up主@吸血小金鱼