个人理解单链表翻转
来源:互联网 发布:广州专利代理待遇知乎 编辑:程序博客网 时间:2024/06/02 07:51
单向链表的反转是一个经常
被问到的一个面试题,也是一个非常基础的问题。比如一个链表是这样的: 1->2->3->4->5 通过反转后成为5->4->3->2->1。最容易想到的方法遍历一遍链表,利用一个辅助指针,存储遍历过程中当前指针指向的下一个元素,然后将当前节点元素的指针反转后,利用已经存储的指针往后面继续遍历。源代码如下:
struct linka { int data; linka* next;};void reverse(linka*& head){ if(head ==NULL) return; linka*pre, *cur, *ne; pre=head; cur=head->next; while(cur) { ne = cur->next; cur->next = pre; pre = cur; cur = ne; } head->next = NULL; head = pre;}
解释:对于头结点后的下一个结点cur如果不为空,则得到它的下一个结点保存在ne结点中,然后把cur的下一个结点赋为cur的前一个结点pre,这样就实现了cur和它的前一个结点的交换,然后把cur结点赋给pre结点,把ne结点赋给cur,这就实现了cur结点和pre结点都向后移了一个结点,然后循环下去,一直到cur结点为空时,说明已到链表尾,这时把头结点的后一个结点指向空,说明头结点已经成了尾结点了,这个时候把pre结点已经是原链表的最尾端了,如果要实现翻转,则把它赋给头结点。
如上图所示,它是先翻转head和p1,使p1指向head,然后pre=cur;cur=ne;到第二次,继续翻转p1,p2,使p2指向p1,然后持续下去,一直到第四次,这时cur为空,而pre已到了原链表的最后一个结点,这时如果head的下一个结点为空,则说明head为链尾了,而pre则变成了链头,然后把它赋给头结点即可。
还有一种利用递归的方法。这种方法的基本思想是在反转当前节点之前先调用递归函数反转后续节点。源代码如下。不过这个方法有一个缺点,就是在反转后的最后一个结点会形成一个环,所以必须将函数的返回的节点的next域置为NULL。因为要改变head指针,所以我用了引用。算法的源代码如下:
linka* reverse(linka* p,linka*& head){ if(p == NULL || p->next == NULL) { head=p; return p; } else { linka* tmp = reverse(p->next,head); tmp->next = p; return p; }}
- 个人理解单链表翻转
- 个人理解
- 单链表翻转
- 单链表翻转
- 单链表翻转
- 单链表翻转
- 单链表翻转
- 翻转单链表
- 翻转单链表
- 单链表翻转
- 单链表翻转
- 翻转单链表
- 单链表翻转
- 单链表翻转
- 翻转单链表
- 单链表翻转
- 单链表翻转
- 单链表翻转
- 通过WMI获取设备名,HID设备获取设备描述符的一个折中办法
- 深入探索.NET框架内部了解CLR如何创建运行时对象
- 如何获取CPU主频----读注册表
- Field of Your Dreams: MLB's Sexiest Cheerleaders
- 数组
- 个人理解单链表翻转
- 感谢 csdn给我带来的帮助!
- 一个CodeBlocks注释问题(不能用//单行注释)
- 关于C++的输出流cout格式化输出
- ASP.NET MVC 概述
- 详解.NET中的动态编译技术
- SQLServer和Oracle的常用函数对比
- BIEE : ibot 配置(Schedule 服务)
- MVC2.0 基础知识