前言
声明:因个人能力有限,本文仅是个人的学习记录笔记,有错误之处还望指出数据结构每日一题
题目
设线性表L为{a1,a2,a3…an-1,an}采用头节点的单链表保存,按要求重新排列L中的各个结点,得到线性表的顺序为{a1,an,a2,an-1…}
要点
- 双指针的使用
- 头插法逆置结点
思想
- 分析插入后的结点的规律是间隔顺序递增,但是给出的后部分结点是递减,且结点可以分为两部分
- 找到中间节点(两个指针,快指针一次走两步,慢指针一次走一步,故在快指针到达链尾的时候,慢指针在中间结点)
- 将后部分的元素逆置(头插法)
- 插入结点(先第一部分的结点+后部分的结点)
typedef struct node{
struct node *next;
int data;
}NODE;
void ChangeList(NODE *h){
LNode *p,*q,*s,*r;
p=h->next;
q=h->next;
//找到中间节点
while(q!=NULL){
p=p->next; //q走一步(慢指针)
q=q->next;
if(q->next==NULL) //判断走一步是否为空,空的话再走一步(快指针)
q=q->next;
}
q=p->next; //p所指为中间结点,q为后半段链表的首结点
p->next=NULL; //断开
//逆置后半段序列(头插)
while(q!=NULL){
r=q->next; //记录位置,防止断链
q->next=p->next;
p->next=q;
q=r;
}
//合并
s=h->next; //s所指向前半段的第一个数据结点
q=p->next; //q所指向后半段的第一个数据结点
p->next = NULL;
while(q!=NULL){ //后半段结点按要求插入
r=q->next; //r指向后半段的第一个结点
q->next=s->next; //q所指向的结点插入s之后
s->next=q;
s=q->next; //s指向前半段的下一个结点
q=r;
}
}