您的位置:首页 > 其它

链表的基本操作应用-reverse

2015-06-20 12:51 302 查看
/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/


链表尤其是单向链表是一个比较简答的问题,一般容易出错的点是对结尾处NULL的考虑不到位。

比如 (1) 此时指针已经为空,然而还要求其next指针。一般是在用循环求解这一类问题时,忽略边界条件的限制,导致ListNode* p==NULL;的时候仍然写出p->next;

(2) 重构链表的时候,没有给最后的结点next赋值为NULL;一般创建的时候不会出现这种问题,因为创建new的时候默认的next值就是NULL;

一般在修改原链表的时候,忽略这一点会带来不小的麻烦。

看下面这非常简单的例子。

1,链表翻转

(1)翻转自然想到是借助一个stack来实现,这里用vector来构建一个stack;

ListNode* reverseList(ListNode* head) {
if(!head) return NULL;
vector<ListNode*> stack;
stack.push_back(head);
while(stack.back()->next!=NULL){
stack.push_back(stack.back()->next);
}
ListNode* p=stack.back();
stack.pop_back();
ListNode* pHead=p;
while(stack.size()>0){
p->next=stack.back();
p=stack.back();
stack.pop_back();
}
p->next=NULL;//不要忘记赋值。
return pHead;
}


优点是:思路清晰,不容易出错。

缺点是:第一次访问链表,然后访问数组,相当于访问了两次这个链表,时间有点多;

空间复杂度为O(n);

(2)考虑3个指针实现。只需要一次遍历链表即可输出。

ListNode* reverseList(ListNode* head) {
if(!head) return NULL;
if(head->next==NULL) return head;
ListNode* p1,*p2,*p3;
for(p1=head,p2=head->next,p3=head->next->next;p1&&p2&&p3;){
if(p1==head) p1->next=NULL;//这个不要忘记了
p2->next=p1;
p1=p2,p2=p3,p3=p3->next;
}
if(p1==head) p1->next=NULL;//这个不要忘记了
p2->next=p1;
return p2;
}
关于为什么需要第三个指针,p2->next=p1;之后,我们无法找到原有的p2下一个结点了。

Reverse Linked List II

For example:

Given
1->2->3->4->5->NULL
, m = 2 and n =
4,

return
1->4->3->2->5->NULL
.

Note:

Given m, n satisfy the following condition:

1 ≤ m ≤ n ≤ length of list.
这题要求比较细心就好。一次ac。
ListNode* reverseBetween(ListNode* head, int m, int n) {
if(!head) return NULL;
if(m==n) return head;
ListNode dummy(-1);
dummy.next=head;
ListNode *p1=&dummy,*p2=&dummy;
for(int i=0;i<m-1;i++){//p1是m的前一个结点
p1=p1->next;
}
p2=p1->next;
for(int i=0;i<n-m;i++){//p2在n位置上
p2=p2->next;
}
ListNode* cur=p1->next;
p1->next=p2;//边界结点大转向
ListNode *prev=cur;
cur=cur->next;
ListNode *post=cur->next;//最坏post=NULL;
prev->next=p2->next;//边界结点大转向
cur->next=prev;
while(post!=NULL&&cur!=p2){
prev=cur;
cur=post;
post=post->next;
cur->next=prev;
}
return dummy.next;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: