您的位置:首页 > 理论基础 > 数据结构算法

链表反转——迭代模型与递归模型

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息