IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 反转链表的几种常用方法 -> 正文阅读

[数据结构与算法]反转链表的几种常用方法

(1)迭代法反转链表

核心思想是设置三个指针分别指向(待被反转后指针指向的结点front????????指针域指向要反转的结点mid????????待被反转的结点last),从头结点开始通过三个指针的移动逐渐完成链表的反转

struct Link* Iteration(struct Link* head)//也可以从头结点开始
{
    struct Link*front=NULL;//使front指向首元结点前的位置
    struct Link*mid=head;//mid指向首元结点
    struct Link*last=head->next;//last指向第二个结点

    if(head==NULL||head->next==NULL)//若链表中只有一个结点则它反转后就是本身
    {
        return head;//返回它本身
    }
    else//若链表中不止一个结点
    {
        while(1)//一直反转直到所有结点的指针域都指向前一个结点
        {
            mid->next=front;//使当前正在反转的结点的指针域指向前一个结点
            if(last==NULL)/*此时需要判断待反转的结点是不是为空,
                            若为空说明此时mid已经是最后一个结点,不用再继续反转*/
            {
                break;
            }
            front=mid;//若反转的不是最后一个结点则把三个指针都向后移一位以进行下一次反转
            mid=last;
            last=last->next;
        }
    }
    head = mid;//使最后一个被反转的结点成为新的首元结点,完成反转
    return head;//返回指向首元结点的指针
}

?(2)递归法反转链表

算法思想和迭代相似但是操作相反(从尾结点开始反转),首先利用递归找到尾结点,再利用递归的逐级返回性质设置一个指针head,让其新指向前一个待反转的从结点直到遇到原头结点,从而逐渐反转链表

/*此处先设置两个结点:前结点和后结点*/

后结点一开始是尾结点,前结点一开始是尾结点的前一个结点,在递归过程中这两个结点一直在一起向前移动(通过递归的逐级返回而移动),此时设置一个head指针让其指向前结点,反转就是让后结点的指针域指向前结点,相当于前结点是待反转的结点,而后结点是正在反转的结点

struct Link* Recursive(struct Link* head)
{
    if (head == NULL || head->next == NULL)//递归出口(并且判断链表是否只存在一个结点)
    {
        return head;/*在链表不只有一个结点的情况下,若找到了尾结点,
        说明此时head->next==NULL,递归返回一层,head作为返回值赋给newhead,
        newhead成为尾结点,而返回后的head是head->next,所以head是倒数第二个结点*/
    }
    else
    {
        //一直递归,直到找到链表中最后一个结点
        struct Link *newhead = Recursive(head->next);//与迭代不同,一开始就找到了新头结点
        /*当逐层退出时,newhead的指向一直不变,一直指向原链表中尾结点(新的头结点),
        而head的指向一直在改变(指向待被反转的结点)*/

        head->next->next = head;/*使head所指结点(前结点)的指针域指向的结点(就是后结点)
        的指针域指向前结点,以确定下一个要反转的结点(就是前结点)*/
        head->next = NULL;//head所指结点的指针域为NULL(若不置为NULL,会使两个结点的指针域互指)

        return newhead;/*每一层递归结束,都要将指向新头结点(尾结点)的指针返回给上一层,
                        保证整个递归过程中,一直找得到新表头(因为最后函数的返回值是反转后的链表头指针,
                        而我们并不知道什么时候递归结束,所以要在每层递归结束后都返回新头指针)*/
    }
}

(3)头插法反转链表

核心思想是从头结点开始顺序取出原链表中的所有结点并把这些结点逐个通过头插法插入到一个空链表中

struct Link *Headinsert(struct Link *head)
{
    struct Link * new_head = NULL;//新创建的链表的头结点为空
    struct Link * temp = NULL;//待插入的结点为空
    if (head == NULL || head->next == NULL) 
    {
        return head;
    }
    while (head != NULL)//当原链表的头结点不为空时
    {
        temp = head;//头结点成为了待插入的结点
        head = head->next;//下一个待插入的结点作为新的头结点

        temp->next = new_head;/*将原链表头结点头插入新链表的头部
        (头插法就是让新插入结点的指针域指向链表的头结点)*/
        new_head = temp;//新的头结点就是新插入的结点
    }
    return new_head;//返回新的头结点,此时原链表的尾结点成为了新链表的头结点,完成反转
}

(4)就地逆置法反转链表

与头插法思想相同,不同在于不用创建新的链表而是直接在原链表上做修改,只不过这样就需要借助两个指针front和last来帮助记录位置

struct Link *Local(struct Link* head) 
{
    if (head == NULL || head->next == NULL)
    {
        return head;
    }
    struct Link * front = head;//创建front指针指向首元结点
    struct Link * last = head->next;//last指向首元结点的下一个结点
    while (last != NULL) //当存在下一个结点的时候
    {
        front->next = last->next;//将last从链表中摘除
        last->next = head;//将last移动至表头
        head = last;//last成为新表头(为反转下一个结点做准备)
        last = front->next;//重置last为需要摘除的下一个结点(原last的下一个结点)
    }
    return head;
}

参考博客:单链表反转详解(4种算法实现)

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章           查看所有文章
加:2021-12-01 17:57:48  更:2021-12-01 18:00:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 14:34:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码