链表逆序经常是面试中常见的一个题目,很多人觉得不好记,下面我教大家两种比较好记的解法。
解法一:迭代解法
void reverse(Node* pNode)
{
// 判断头和头next不为空,必须有两个以上的结点才能反序
if (NULL == pNode || NULL == pNode->next)
{
return;
}
// 三个指针 分别指向链表的前三个结点(注意:如果链表只有两个结点也是可以的)
Node* p1 = pNode;
Node* p2 = pNode->next;
Node* p3 = p2->next;
// 头部变尾部 指向NULL
p1->next = NULL;
// 判断的是最后一个
while(p3)
{
// 每次只反序中间
p2->next = p1;
// 前、中、后每个向后移动一个单位
p1 = p2;
p2 = p3;
p3 = p3->next;
}
// 循环结束 再反序中间
p2->next = p1;
// 最后将中间返回
pNode = p2;
}
那么如何记住解法呢?记住以下五个步骤即可:
1. 链表判断是否有两个以上结点(必须条件)
2. 定义三指针分别指向前三个
3. 头指向null
4. 循环判断如果第三个不为空,则执行以下两步,第一步、反序中间、第二步、三指针从p1开始顺序往后移动一个单位
5. 最后再反序中间一次,然后将中间返回
或者记住以下关键字
三个指针、循环判断的是第三个、顺序移动三个指针、只反序中间
按照这种思路,应该很快就可以记住了
解法二:利用栈(对于实在记不住第一个解法的同学)
定义一个栈、因为栈有先进后出的特点,所以只要按照顺序入栈再出栈,链表就可以反序了
解法三:递归解法
Node * ReverseList(Node *node)
{
if (!node || !node->next) {
return node;
}
Node* p1 = node->next;
Node* p2 = ReverseList(p1);
p1->next = node;
node->next = NULL;
return p2;
}