一、代码
先放出代码:
【注】表尾指针 r
按需设置,在单链表的逆置过程中并不重要。
void ReverseList(LinkList &L) {
LNode *r = L->next; // 建立表尾指针,其实可以不要
LNode *s = r->next;
LNode *p = s->next;
r->next = NULL;
while (p) { // 进入“头插法”循环
s->next = L->next;
L->next = s;
s = p;
p = s->next;
} // 循环结束后,还存在最后一个节点没有插入
s->next = L->next;
L->next = s;
}
二、分析
以
带头结点的4元素单链表
演示,先说明大致步骤:
① 建立指针 r, s, p
。r
指向“新表”(逆序后)的末尾结点;s
指向待插入的下一个结点;p
指向待插入结点的下一个结点。
② 进入循环。循环内使用 头插法
。将 s, p
指针依次往后推移,利用头插法得到逆序的原理,插入头结点 L
之后。
【注】循环退出的条件,我是以 p
是否指向 NULL
来判定。当 p == NULL
时,s
还指向最后一个节点,因此需要在退出循环后再“头插”一次。
三、验证
写一段小代码进行验证:
【注】LinkList.h
结构体头文件:前文 单链表与双链表-线性表的链式表示 详解。
#include "LinkList.h"
void CreateList_TailInsert(LinkList &L) {
L = (LNode*)malloc(sizeof(LNode));
LNode *t, *r = L; // 指针 r 一直指向链表 L 的尾部
ElemType x;
cin>>x;
while (x!=9999) {
t = (LNode*)malloc(sizeof(LNode));
t->data = x;
r->next = t;
r = t;
cin>>x;
}
r->next = NULL; // 链表尾部之后为 NULL
}
void PrintList(LinkList L) {
cout<<"output: ";
while (L->next!=NULL) {
L = L->next;
cout<<L->data<<" ";
}
cout<<'\n'<<"----------------"<<'\n';
}
void ReverseList(LinkList &L) {
LNode *r = L->next; // 建立表尾指针,其实可以不要
LNode *s = r->next;
LNode *p = s->next;
r->next = NULL;
while (p) { // 进入“头插法”循环
s->next = L->next;
L->next = s;
s = p;
p = s->next;
} // 循环结束后,还存在最后一个节点没有插入
s->next = L->next;
L->next = s;
}
int main() {
LinkList L;
cout<<"TailInsert: ";
CreateList_TailInsert(L); // 建表
PrintList(L);
ReverseList(L); // 逆序
PrintList(L);
return 0;
}
运行结果如下:
更新时间——2023/3/1