【Leecode刷题】反转链表(206)史上最详细系列刷题(含自己环境运行全代码)
注:交Leecode只交Solution即可,这等于我们做好了函数直接调用,但是主函数怎么做,一些具体的数据结构和输入输出操作我们并不好掌握,本系列给的是一道题最完完整整的思路,更多内容请查看链接
反转链表
方法一:直接逆置法 c l a s s S o l u t i o n class\,Solution classSolution
传入头结点进行反转,也即为上传 L e e c o d e Leecode Leecode代码,传入头结点,将每一个结点的指针进行逆置,返回头结点
lass Solution
{
public:
ListNode* reverseList(ListNode* head)
{//函数传入原链表的头结点指针head
/*
当明确结点个数时
for(int i=0;i<5;i++)
{
next=head->next;//把原来列头结点的下一个结点位置进行备份
head->next=reverse;//将原来列结点的第一列断开,使他指向新列表的头结点
reverse=head;//把reverse指向新列表头结点
head=next;//head指向原列表的下一个结点
list_print(head,"old_list");
lit_print(head,"reverse_list");
}
*/
//不明确结点个数时
ListNode *reverse=NULL;
ListNode *next=NULL;
while(head){
next=head->next;//把原来列头结点的下一个结点位置进行备份
head->next=reverse;//将原来列结点的第一列断开,使他指向新列表的头结点
reverse=head;//把reverse指向新列表头结点
head=next;//head指向原列表的下一个结点
}
return reverse;
}
};
方法二:头插法 c l a s s S o l u t i o n class\,Solution classSolution
设置额外临时头结点 t e m p temp temp,利用 h e a d head head指针遍历原链表,每遍历一个结点,即将 h e a d head head访问的结点插入 t e m p temp temp结点后,当所有的结点都插入 t e m p temp temp结点后的时候, h e a d head head指向空
class Solution//直接逆置法
{
public:
ListNode* reverseList(ListNode* head)
{
ListNode temp(0);
ListNode *next=NULL;
while(head){
next=head->next;
head->next=temp.next;
temp.next=head;
head=next;
}
return temp.next;
}
};
然后补全代码
- 首先设置数据结构,设一个链表结点
struct ListNode
{
int val;//结点存储的数据
ListNode *next;//指向下一个节点的指针
ListNode(int x):val(x),next(NULL){}//构造函数,将val的值赋为x,next的值赋为空
};
- 打印链表的方式,按结点不断输出,若识别为空则退出,
void list_print(ListNode *head,const char *name){
printf("%s",name);
if(!head){
printf("NULL\n");
return;
}
while(head){
printf("[%d]",head->val);
head=head->next;
}
printf("\n");
}
- 加主函数
int main()
{
ListNode a(1);//构造5个结点a、b、
ListNode b(2);
ListNode c(3);
ListNode d(4);
ListNode e(5);
a.next=&b;//将a,b,c,d,e5个结点依次连接到一起
b.next=&c;
c.next=&d;
d.next=&e;
Solution solution;
ListNode *head=&a;//指向链表的头结点a
list_print(head,"old_list");//打印原始链表
head=solution.reverseList(&a);
list_print(head,"reverse_list");//打印逆置后的链表
/*
ListNode *reverse=NULL;//新链表头结点指针,最初指向空
ListNode *next= NULL;//用来备份当前操作结点的下一个结点的地址
*/
return 0;
}
所有代码汇总,直接能跑的程序
#include<stdio.h>
struct ListNode
{
int val;//结点存储的数据
ListNode *next;//指向下一个节点的指针
ListNode(int x):val(x),next(NULL){}//构造函数,将val的值赋为x,next的值赋为空
};
void list_print(ListNode *head,const char *name){
printf("%s",name);
if(!head){
printf("NULL\n");
return;
}
while(head){
printf("[%d]",head->val);
head=head->next;
}
printf("\n");
}
class Solution
{
public:
ListNode* reverseList(ListNode* head)
{//函数传入原链表的头结点指针head
/*
当明确结点个数时
for(int i=0;i<5;i++)
{
next=head->next;//把原来列头结点的下一个结点位置进行备份
head->next=reverse;//将原来列结点的第一列断开,使他指向新列表的头结点
reverse=head;//把reverse指向新列表头结点
head=next;//head指向原列表的下一个结点
list_print(head,"old_list");
lit_print(head,"reverse_list");
}
*/
//不明确结点个数时
ListNode *reverse=NULL;
ListNode *next=NULL;
while(head){
next=head->next;//把原来列头结点的下一个结点位置进行备份
head->next=reverse;//将原来列结点的第一列断开,使他指向新列表的头结点
reverse=head;//把reverse指向新列表头结点
head=next;//head指向原列表的下一个结点
}
return reverse;
}
};
int main()
{
ListNode a(1);//构造5个结点a、b、
ListNode b(2);
ListNode c(3);
ListNode d(4);
ListNode e(5);
a.next=&b;//将a,b,c,d,e5个结点依次连接到一起
b.next=&c;
c.next=&d;
d.next=&e;
Solution solution;
ListNode *head=&a;//指向链表的头结点a
list_print(head,"old_list");//打印原始链表
head=solution.reverseList(&a);
list_print(head,"reverse_list");//打印逆置后的链表
/*
ListNode *reverse=NULL;//新链表头结点指针,最初指向空
ListNode *next= NULL;//用来备份当前操作结点的下一个结点的地址
*/
return 0;
}