题目描述:反转一个单链表。
题目示例:
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
题目思路:
首先拿到这个题目,我们先要知道题目的意思是什么,就是我们现在有一个已经存在的链表,但是链表的顺序需要进行翻转,这个很容易理解,但我们仔细的思考下,肯定不是简单的交换地址域,因为在链表的最后节点,是NULL ,而当我们进行翻转链表以后,我们的头结点是在最后的位置,所以我们仍然需要在原头结点的后面加上尾结点NULL 。
我们考虑用两种方法来作答:第一种迭代算法,第二种递归算法。
第一种方法,迭代算法:
我们来整理下思路:
如上图所示,我们需要在每一个迭代的过程定义三个指针变量用于存放变量,在某一时刻,firsrt=2 ,second,third=3, 我们先将下一个结点赋值给third,用于展示存放,然后将2和3的指向关系互换,最后将first和second赋值到下一轮的迭代中。
在思路很明确的前提下,我们来进行代码实现,请注意,这里别忘记了异常处理的情况。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == NULL || head->next == NULL){
return head;
}
ListNode* first= NULL;
ListNode* second = head;
ListNode* third = NULL;
while(second){
third=second->next;
second->next=first;
first=second;
second=third;
}
return first;
}
};
第二种思路:递归的算法
可能有些不是太好明白,就是递归的思想,我们可以从少一点的元素进行思考,假设有三个元素,每次递归下去都是头结点发生变化,当递归到第三个节点的时候,触发结束条件,返回头结点,这样我们会先返回第三个结点,然后再递归回第二个结点,最后是第一个结点。
那我们来看下代码实现:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == NULL || head->next == NULL){
return head;
}
ListNode* q=head->next;
ListNode* new_head = reverseList(q);
q->next=head;
head->next=NULL;
return new_head;
}
};
最后的时候需要把前面两个结点在连接上,因为需要把最开始的头结点当成倒数第二个结点,然后并把该结点指向NULL 。