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

版权声明:本文为博主原创作品,转载请在正文明显处注明出处。

数据结构:相互之间存在一种或多种特定关系的元素的集合。


单链表反转有迭代递归两种算法。

首先,定义结点:
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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值