单向链表的翻转
单向链表翻转 思路
假设链表是: 1->3->5->∅,所要求得的链表是 5->3->1->∅。只需要将每个节点的 next 指向其之前的一个节点即可。
对于第一个节点,如果是头节点不带数据的链表,那么只需要将其 next 指向 head;如果头节点带数据,第一个节点的 next 指向NULL。在进行操作过程中,我们用 pre 标记之前的节点, cur 标记当前的节点,当 cur 指向的节点的 next 指向前一个,那么就发了改变,所以同时我们还需要保存每个节点 cur 的 next 指向的节点,由此来往后进行操作。直到最后所有节点翻转结束,此时的 pre 指针指向了当前完成翻转后链表的头,如果是有无数据头节点的链表,将其 head 的 next 指向当前的 pre 即可。
单向链表翻转 图解
cur指向第一个带数据节点,nex保存下一节点
cur的next指向前一个节点
此时头节点head应当指向第一个节点, 但是为了图解美观可以暂时不管它,后面也是这样
pre指向当前的cur, cur指向下一个节点
重复之前翻转的操作
此时cur指向了NULL, 退出循环
最后head接回, 其next指向当前pre指向的节点
单向链表翻转 核心代码
void Reverse_Linklist(Linklist *head){
Linklist *cur = head->next;
Linklist *pre = NULL;
while(cur){
Linklist *nex = cur->next;
cur->next = pre;
pre = cur;
cur = nex;
}
head->next = pre;
}
完整程序及测试
程序代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int Elemtype;
typedef struct Node {
Elemtype data; //结构体数据域
struct Node *next; //结构体指针域
} Linklist;
Linklist* Initial_linklist(Linklist *mylist){
mylist = (Linklist *)malloc(sizeof(Linklist));
mylist->next = NULL;
return mylist;
}
//创建初始链表 尾插法
void Create_linklist(Linklist *head, int n) { //头节点(不带数据)
Linklist *node, *end; //普通节点 尾节点
end = head; //当链表为空时 头尾指向同一个节点
printf("创建链表输入 %d 个元素:\n", n);
for (int i = 0; i < n; i++) { //n为插入普通节点的个数
node = (Linklist *)malloc(sizeof(Linklist));
scanf("%d", &node->data);
end->next = node; //之前的end的next指向了新的节点node
end = node; //end往后移,此时新的节点变成尾节点
}
end->next = NULL; //end最后置NULL
}
//遍历输出链表
void Show_linklist(Linklist *head) {
Linklist *node = head->next;
if (node == NULL)
puts("链表为空");
while (node != NULL) {
printf("%d ", node->data);
node = node->next;
}
printf("\n\n");
}
//翻转链表
void Reverse_Linklist(Linklist *head){
Linklist *cur = head->next;
Linklist *pre = NULL;
while(cur){
Linklist *nex = cur->next;
cur->next = pre;
pre = cur;
cur = nex;
}
head->next = pre;
}
int main() {
//头指针初始化
Linklist *mylist;
mylist = Initial_linklist(mylist);
int n;
printf("输入创建初始链表元素个数: ");
scanf("%d", &n);
Create_linklist(mylist, n);
printf("初始状态链表:\n");
Show_linklist(mylist);
Reverse_Linklist(mylist);
printf("链表进行翻转后:\n");
Show_linklist(mylist);
}