链表的逆序应该是面试题中比较经典的题目了。
自己也写过了很多的次,还是不能深刻的理解。特写博客记录。
链表的逆序一般有两种写法:循环写法和递归写法
循环写法:(非常的简单)
思路就是:用一个临时指针记录当前逆序的结点。
比如说 pHead 一直用来记录原链。 p 用来记录当前的结点。 root 用来记录逆序后的头结点
Code:
<span style="font-size:18px;">class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
// 代码的鲁棒性是每一个程序必须考虑的问题。。PPPPPs
if(pHead == NULL) return pHead;
ListNode *root = new ListNode(-1);
while(pHead != NULL){
ListNode *p = pHead;
pHead = pHead -> next; // 这句必须在下面的两句之前。
// 否则会出现的问题就是,原链不能够正确的记录。
p -> next = root -> next; // if root -> next = NULL
root -> next = p;
}
return root -> next;
}
};</span>
#########
递归写法:
递归写法比较难以理解(主要是针对我来说的),主要的原因在于对于递归的理解还没有那么的深刻。
Code:
class Solutions {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead == NULL || pHead -> next == NULL) return pHead;
ListNode* newhead = ReverseList(pHead -> next);
pHead -> next -> next = pHead;
pHead -> next = NULL; // 把原来链断开。
return newhead;
}
};
一开始没有很好的理解:
pHead -> next -> next = pHead;// 在原来的链上,还没有断掉的情况下,该句话的意思就是把后面的结点的下一个结点赋为当前结点
// 下面的code 就是把原链断掉。
pHead -> next = NULL; //这里的意思是把原来的链给断掉。
newhead 的话,始终是指向的新链的头结点。
递归参数为两个,思想的话,和一个参数差不多,只不过久是用last来记录下一个结点,其他的无所谓。
Code:
class Solutionz{
public:
/* 递归翻转链表:(传两个参数)
* 思想的话和传一个参数差不多:
* last 记录后面一个结点,pHead为当前结点。
*/
ListNode* ReverseList(ListNode *pHead, ListNode *last){
if(pHead == NULL || last == NULL) return pHead;
ListNode *newhead = ReverseList(last, last -> next);
last -> next = pHead;
pHead -> next = NULL;
return newhead;
}
};
######
链表的倒置的话,基本上就这些了。如果有其他的以后补。2015/7/8