史上最全的反转链表
Posted 勇敢*牛牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了史上最全的反转链表相关的知识,希望对你有一定的参考价值。
史上最全的反转链表!!!
**震惊!!!**一个小小的反转链表,竟然有好几种方法,还要看好几篇文章,更要命的是观看需要money!!!!哎,气不过,我就给你整合到一起,我就写 保姆级别教程+源代码,纯干货,全免费,都公开!
放在电脑上就能整!!!!
开整:
/***********************************************************
*版权所有:© 2021.8.5 烽火编程(第八方面军)
*文件名称:递归解决翻转单链表
*内容摘要:递归 ,循环,三指针
*当前版本:1-1
*文件作者:帅子牛
*完成日期:2021.8.5
*修改记录:暂无
***********************************************************/
#include <stdio.h>
#include <malloc.h>
typedef struct list{
int data;
struct list* next;
}List,*list; //这里不懂的话,可以翻我的 "单链表" 进一步了解
list InitList(){//初始化有头结点的链表
list head = (list)malloc(sizeof(List));
head->next = NULL;
return head;
}
void CreatList(list head,int n){//头插法建立单链表
list s;
int i;
for(i=0;i<n;i++){
s = (list)malloc(sizeof(List));
scanf("%d",&s->data);
s->next = head->next;
head->next = s;
}
printf("单链表建立完毕\\n");
}
/*反转链表的输出*/
int DisPlay_1(list head){ //代码反转后结构发生轻微变化,需要读者思考与原链表的不同之处
list s = head;
if(head == NULL){
return 0;
}
while(s->next != NULL){
printf("%d ",s->data);
s = s->next;
}
return 1;
}
/*递归输出单链表(我自码的,读者可自行递归探索是否正确)*/
int DisPlay(list head,list s){
if(head == NULL || s == NULL){
return 0;
}else{
printf("%d ",s->data);
DisPlay(head,s->next);
}
}
/*
//一般单链表输出
void DisPlay(list head){
list s = head->next;
while(s){
printf("%d\\t",s->data);
s = s->next;
}
printf("\\n");
}
*/
/*
*三指针法,反转单链表
*a,b,c三个指针分别指向三个位置
*a和b指针用来反转两个结点
*c指针指向下一个结点用来标记和前移
*/
list reverList(list head){//单链表反转函数-1
list a,b,c;
a = head;
b = a->next;
c = b;
a->next = NULL;
while(b != NULL){
c = c->next;
b->next = a;
a = b;
b = c;
}
return a;
}
/*
*三指针法优化,但是他们大概的思路是一致的
*a,b,head三个指针分别指向三个位置
*a和 head指针用来反转两个结点
*b指针指向下一个结点用来标记和前移
*/
list reverList_1(list head){//单链表反转函数-2
list a=NULL,b=NULL;
while(head != NULL){
b = head->next;
head->next = a;
a = head;
head = b;
}
return a;
}
//递归法
/*
*按照之前的递归按要素走:寻找等价关系:想最简单的一种情况:即只有两个结点时之接进行翻转
*那接下来该怎么如何把这两个结点翻转呢?其实就是如下
*p->next->next = p;原第二个指向第一个 ,第一个指向空
*p->next = NULL;
* 也就是说:reverList_2(list head)等价于reverList_2(head->next) 改变一下最后两个的结点就行
*至此递归的等价关系就找了出来
*/
list reverList_2(list head){
list p;
p = head;
if(p->next == NULL || p == NULL){ //出口:当链表只有一个结点或者是空表的话之接返回就行
return head;
}
if(p->next->next == NULL){ //只有两个结点的情况之接翻转
head = p->next;
p->next->next = p;
p->next = NULL;
}else{
head = reverList_2(p->next);
/*超过两个的话,指针向后遍历,将最后两个翻转,
翻转完了之后当前结点 和后一个结点可以看做是最后两个结点*/
p->next->next = p;
p->next = NULL;
}
return head;
}
int main() {
list head = NULL;
head = InitList();
CreatList(head,5);
printf("正常单链表的顺序为:");
DisPlay(head,head->next);
// printf("\\n三指针法翻转后的单链表:");
// list font = reverList(head);
// DisPlay_1(font);
// printf("\\n三指针法(优化)翻转后的单链表:");
// list font = reverList_1(head);
// DisPlay_1(font);
printf("\\n递归翻转后的单链表:");
list font = reverList_2(head);
DisPlay_1(font);
return 0;
}
结果演示:
以上是关于史上最全的反转链表的主要内容,如果未能解决你的问题,请参考以下文章
史上最全Hashmap面试总结,51道附带答案,持续更新中...