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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 链表类算法题简介及思路总结(包含递归法的理解使用) -> 正文阅读

[数据结构与算法]链表类算法题简介及思路总结(包含递归法的理解使用)

部分内容来源于 https://www.programmercarl.com/

0.引言

链表是非常基础的一种数据结构,在删除和插入方面比传统的数组结构更加的简单。

1.链表基础结构

1.1 什么是链表

链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。

链接的入口节点称为链表的头结点也就是head。

1.2 链表分类

  • 单链表。即只有一个指向后一个节点的指针。

  • 双链表。每个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。

  • 循环链表。链表首尾相连。

1.3 链表存储方式

数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。

链表是通过指针域的指针链接在内存中各个节点。

所以链表中的节点在内存中不是连续分布的 ,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。

2.链表题常用思路

2.1 双指针法

在链表题中,也可以考虑双指针法。

2.2 递归法

链表特别适合使用递归的算法,因为很多链表的算法题都需要对节点进行一个个的判断。遇到这种类型的题目就可以考虑递归的方法。

底下是一个比较通用的递归代码模板,不同于其他的递归教程,这套流程针对性很强,可以很容易套进题目之中,具体流程和代码如下。

首先要明确递归的流程,在链表递归函数运行过程中,主要分为三个部分,1.每个节点依次进入递归函数,2.遇到边界条件后进行返回,3.一直返回到递归起点。

接下来,针对以上流程,进行递归代码的分解讲解。

首先,在编写之前,先确定好,以上3个部分中的13过程中,需要在哪个部分进行逻辑的处理。

  • 在1过程需要进行逻辑处理,及从头到尾,每次进入递归函数,都会进行一个逻辑的处理,此时处理逻辑代码要写在递归函数之前。如果要将此次处理的结果传给后续节点,此时可以将变量设置为递归函数的变量进行传递,这样在每次往后递归之前都会先运行逻辑函数,并将得到的结果往后传递。
  • 在3过程进行逻辑处理,即从后往前进行逻辑处理,此时逻辑代码要写在递归函数之后,返回值之前。 如果要将每次处理的结果传递给前面的节点,此时可以将节点为返回值,这样在每次递归函数运行结束后,会运行逻辑代码,并将返回值返回。

其次,在确定好逻辑代码过程后,可以实际开始编写代码了,第一步就是要写好退出条件,在链表中即表现为当前节点为空的情况,即已经到达最尾部了。

最后,补全最开始确定的逻辑代码,就可以完成整个递归函数的编写了。

func help(head *ListNode,n int)int{
    //停止条件
    if head==nil{
        return n,false,nil
    }
    //往下递归前做的事情,n为往下传入的值
    num:=help(head.Next,n)
    //递归返回时做的事情
    if num==0{
      //做一些处理
    }
    return num //向上传递
    }

1.1 题目训练

1.1.1 反转链表

206. 反转链表 - 力扣(LeetCode)

Solution

按照以上的逻辑,可以使用两种方法,一种是在第一部分(从前往后)进行逻辑的处理,一种是在第三部分(从后往前)。

第一部分进行逻辑处理的时候,我们在首先要存好当前遍历的节点的下一个节点的地址,因为进行反转之后就找不到地址了。然后进行正常的反转即可,代码如下。

第三部分进行逻辑处理时,比较麻烦,首先反转的时候,我们需要前一个节点的地址,而从前往后传递只能作为递归函数的变量进行传递,所以我们设置递归函数其中一个变量为pre,进行传递。然后我们还需要返回最后一个节点,而从最后一个节点往前传值需要作为返回值传递,所以我们设置一个返回值即可,代码如下。

Code

//从前往后的逻辑处理
func reverseList(head *ListNode) *ListNode {
    return help(nil, head)
}

func help(pre, head *ListNode)*ListNode{
    if head == nil {
        return pre
    }
    next := head.Next
    head.Next = pre
    return help(head, next)
}

//从后往前的逻辑处理
func reverseList(head *ListNode) *ListNode {

    return help(head,nil)
}

func help(head *ListNode,pre *ListNode)*ListNode{
    if head==nil{
    return nil
    }
    result:=help(head.Next,head)
    if head.Next==nil{
        result=head
    }
    head.Next=pre
    return result
}

2.3 迭代法

利用迭代法,可以很快的对每个节点进行判断和操作。

2.4 虚拟头结点

链表的一大问题就是操作当前节点必须要找前一个节点才能操作。这就造成了,头结点的尴尬,因为头结点没有前一个节点了。每次对应头结点的情况都要单独处理,所以使用虚拟头结点的技巧,就可以解决这个问题

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:48:39  更:2022-07-17 16:52:07 
 
开发: 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/25 23:47:54-

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