实现链表反转的3种形式(笔记版)
·
链表反转是数据结构中的经典问题,本文给出的主要有迭代法、递归法、栈操作法三种实现方式来实现链表反转。
一、链表基础结构定义
struct Node {
int data; // 节点存储的数据
Node* let; // 指向下一个节点的指针,名字也可以叫next,叫什么无所谓
};
Node* head = nullptr; // 链表头指针(初始为空)
通过结构体定义了一个链表节点(Node),每个节点包括整型的data和一个指针类型的next指针,用来存储下一个节点的地址。并初始化头节点,将head指针的指向设置为null(也可以说是0)。
因为嫌麻烦,比较懒。实现的流程图就选择手绘,不美观但是实用。
因为bro编关于这类代码就是看着下面的流程图写的。


方法1:迭代法
思路:
通过三个指针(current、prev、next)逐个反转节点间的指向关系,逐步将链表方向倒置。
Node* ReverseIterative() {
Node* current,*prev,*cnext;
current = head;
Node* prev = nullptr;
temp = head;
while(current != nullptr){
cnext = current ->let;//链表断开前用指针cnext存储下一个节点的当前地址值
current ->let = prev;//prev是反转后链表temp的前一个节点的指针
prev = current;//prev右移
current = cnext;//current右移
}
head = prev;
return head;
}
实现逻辑如下图:


方法2:递归法
思路:
利用递归的栈特性,从链表尾部开始逐层反转节点指向,最终将整个链表方向倒置。
打印链表:
打印链表也可以实现链表的反转
void reversePrint(Node* p){
if(p == NULL){//在NULL前一直会递归调用,一直到NULL都执行Print(p->next);然后输出的值是反过来的
cout << "/n" << endl;
return;
}
//打印的反转或者不反转,其实区别在于下面两条语句的顺序
Print(p->next);//在stack区
cout << p->data << endl;
}
如下图所示(RP为reversePrint函数)

递归实现一个链表的反转
void ReversePrint(Node* p){
if(p->next == NULL){//递归退出条件
head = p;
return;
}
ReversePrint(p->next);//达到退出条件前,一直执行ReversePrint(p->next);
Node* q = p->next;//编号3
q->next = p;//这两行代码可以写成p->next ->next = p;
p->next = NULL;
}

递归方法2:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 递归终止条件:空链表或单节点链表
if (head == nullptr || head->next == nullptr) {
return head;
}
// 递归反转后续链表,得到新头节点
ListNode* newHead = reverseList(head->next);
// 调整指针方向:将当前节点的下一个节点的next指向当前节点
head->next->next = head;
// 断开当前节点的原指向,防止循环,这个思路也可以用快慢指针似乎
head->next = nullptr;
// 返回新头节点
return newHead;
}
};
方法3:栈操作法
思路:
利用栈的后进先出(LIFO)特性,将链表节点依次压入栈中,再依次弹出并重新连接,即可实现反转。
void Reverse(){
stack<Node*> S;//压入栈中的是指针,是地址
stuct Node{
int data;
Node* next;
}
Node *temp = S.top();//指向栈顶,当前最后一个节点的引用
head = temp;
S.pop();
while(!S.empty()){
temp->next = S.top();
S.pop();
temp = temp->next;
}
temp->next = NULL;
}
如此就可以通过三种方式实现了链表的反转。
注:部分思路和代码参考了印度数据结构大神Harsha Suryanarayana的课程。
感兴趣的佬可以去看这位大神的网课,非常推荐。
或者觉得数据结构学得不好,学不懂的非常建议去看他的网课,绝对比学校的好,通俗易懂。
b站上面就有很多。
因为学一下还是有好处,锻炼一下您的脑子,让它比之前更聪明一点。
如有错误,欢迎指出!感谢您,因为代码不是最近写的。
更多推荐


所有评论(0)