链表的基本操作应用-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; }
相关文章推荐
- testng 教程之使用参数的一些tricks配合使用reportng
- 【设计模式】单例模式详解
- js对象
- C#如何生成随机不重复的数字
- 3.MyBatis 入门程序
- vim的学习小小笔记
- Python----matplotlib详细介绍
- 运行及总结
- Windows 2008 + SQLServer 2008 双机群集
- SGU 246. Black & White(数论)
- 回忆我的大学
- 黑马程序员——IO流(一)
- 漫游Kafka实战篇clientAPI
- Sql Server 中非常强大的日期格式化函数
- 【C++探索之旅】第一部分第二课:C++编程的必要软件
- sgu273:Game Po(dp)
- PHP传值、传引用
- 关于独立游戏的一些素材网站
- 单例模式
- 单例模式