版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38088298/article/details/85297092
- 描述:Reverse a singly linked list.
Example:
Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL
- 分析:链表经典题,给定一个单链表,求将它反转之后的链表。
- 思路一:迭代法。
可以将迭代法执行过程理解为如下操作:
1.将原链表头节点之后的节点依次执行删除操作
2.将每次要删除的元素存入临时变量
3.定义一个新链表来存放每次得到的部分链表逆
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* p = head; // 临时变量
ListNode* new_head = head; // 新链表头部
if (head == NULL) return head;
while (head -> next != NULL) {
p = head -> next; // 存放将要删除的元素
head -> next = p -> next; // 将原链表中的元素删除
p -> next = new_head; // 将临时变量中元素和新头部进行拼接
new_head = p; // 产生新链表
}
return new_head;
}
};
思路二:递归法。
递归法与迭代法不同的是递归是先递归访问到最后一个节点作为新链表的头节点,然后递归将节点反向插入到新链表中。
可以将递归法过程看作如下三种状态:
1.链表为空
return NULL直接返回,属特殊情况。
2.递归遍历到尾节点
return head作为开始退出递归的标志,也就是递归遍历到尾节点,将尾节点作为新链表的头节点。
3.递归插入节点
递归遍历到尾节点之后,new_head指向最后一个节点,此时head指向倒数第二个节点,此时先让head->next->next = head成环
然后将这个环断开,head->next = NULL
之后依次执行这个成环
&断开
操作,此时new_head位置不再改变,只是每次在尾部进行一个插入操作。
成环
断开
最终得到一个反转数组。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head -> next == NULL) return head;
ListNode* new_head = reverseList(head -> next);
head -> next -> next = head;
head -> next = NULL;
return new_head;
}
};