链表反转——迭代模型与递归模型
2016-09-08 00:00
169 查看
版权声明:本文为博主原创作品,转载请在正文明显处注明出处。
数据结构:相互之间存在一种或多种特定关系的元素的集合。
每一个结点由数据域和指向下一个结点的指针域组成;
只能直接找到一个结点下一个结点(直接后继),并不能找到上一个结点(直接前驱)。
迭代内部操作(循环的每一轮):当前结点的直接后继改为直接前驱——即当前结点的指针域指向上一个结点;
关于上一点,需要维护一个直接前驱的指针,因为当前结点包含了直接后继的信息,但没有直接前驱;另外循环体的最后要将当前结点地址赋值给直接前驱,准备下一轮循环。
代码:
函数体内部,在调用自己之前的代码为递归终止条件,调用自己之后的代码为假定子部分成立,要做的操作。
代码:
数据结构:相互之间存在一种或多种特定关系的元素的集合。
单链表反转有迭代和递归两种算法。
首先,定义结点:
struct ListNode { int val; ListNode* next; ListNode(int v):val(v),next(nullptr){} };
单链表的特点
由结点组成;每一个结点由数据域和指向下一个结点的指针域组成;
只能直接找到一个结点下一个结点(直接后继),并不能找到上一个结点(直接前驱)。
链表反转的迭代模型
迭代本质是遍历,因此迭代的外部操作为:循环(循环对象为链表上的每一个结点);迭代内部操作(循环的每一轮):当前结点的直接后继改为直接前驱——即当前结点的指针域指向上一个结点;
关于上一点,需要维护一个直接前驱的指针,因为当前结点包含了直接后继的信息,但没有直接前驱;另外循环体的最后要将当前结点地址赋值给直接前驱,准备下一轮循环。
代码:
ListNode* reverseList(ListNode* head) { if(head == NULL || head->next == NULL)return head; ListNode* pre = NULL, cur = head; while(cur) { ListNode* next = cur->next; cur->next = pre; // update: both pre and cur go to the next node; pre = cur; cur = next; } return pre; }
链表反转的递归模型
递归就是自己调用自己,它是一种“往复”模型,需要一级一级调出去(直到终止条件),然后再一级级返回来;函数体内部,在调用自己之前的代码为递归终止条件,调用自己之后的代码为假定子部分成立,要做的操作。
代码:
ListNode* reverseList(ListNode* head) { if(head == NULL || head->next == NULL) return head; ListNode* node = reverseList(head->next);// 先反转后面的链表 head->next->next = head;// 假定head->next之后的链表全反转, // 那么将head结点设为head->next的后继 head->next = NULL; return node; }
相关文章推荐
- 链表反转,递归,迭代
- 反转链表的迭代实现和递归实现
- 递归,迭代,堆栈三种方式实现单链表反转(C++)
- LeetCode 206 Reverse Linked List(反转链表)(四步将递归改写成迭代)(*)
- 反转链表:迭代和递归的实现
- LeetCode 206 Reverse Linked List(反转链表)(Linked List)(四步将递归改写成迭代)(*)
- 合并两个排序链表--迭代和递归分别实现
- 链表反转(使用递归和非递归两种方式)
- 【100题】反转链表(递归实现)
- Java单双链表的创建、反转与递归反转
- 单链表反转(递归和非递归)
- C/C++面试程序题(一)——字符串反转、链表反转的递归、非递归实现
- 如何使用递归和非递归方式反转单向链表
- 链表的建立与反转(递归反转和非递归反转)
- 使用递归和非递归方式反转单向链表
- 关于链表逆置的递归和迭代方法
- 由一道题看链表指针的反转、栈操作(递归)
- 链表翻转的迭代和递归解法
- 反转链表的循环方式和递归方式
- 单链表反转的递归方法