前言
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
一、头插法
void List_Reverse(LinkList L){
if(L-next == NULL)
return;
LNode *p = L->next, *q;
L->next = NULL;//这个要置为NULL,而不是让它指向第一个节点,因为要用它做新表的尾结点
while(p != NULL){
q = p->next;//设置一个q指针来表示p指针的下一个节点的位置
p->next = L->next;//先指向后续节点,防止链表断裂
L->next = p;
//这里不可以直接写成p = p->next;因为上面的指向操作已经使p指针与后面的指针断裂了
//这也是为什么要设置q指针的原因
p = q;
}
}
二、使用三个相邻的指针完成逆序(画图理解)
pre,p,r(顺序排列)为三个相邻的指针。(画图)
1.经过若干次变换后,pre之前的指针已经调整完成,就是它们的next都指向它们原来的前驱节点,现在令p的next指向per。但是一旦动p,p后面的指针就会断开,所以我们需要在定义一个指针r,用它来指向p的后继节点。
2.第一个节点要置为NULL,而不是让它指向第一个节点,因为要用它做新表的尾结点(和头插法一样);处理完最后一个节点后,要将头结点的指针指向它(p)。(画图)
void List_Reverser2(LinkList L){
if(L->next == NULL) return;
LNode *p = L->next, *r = p->next, *pre;
p->next = NULL;//处理第一个节点
while(r != NULL){//如果r为空,说明p为第一个节点
pre = p
p = r;
r = r->next;
p->next = pre;//指针翻转
}
L->next = p;
return;
}
总结
提示:在反向输出的时候,头插法还是很方便的。以上两个方法的时间复杂度O(n),空间复杂度O(1)