代码随想录算法训练营第三天|链表part01

78 阅读3分钟

链表理论基础及训练

一.链表理论

1.基本样貌:链表是一种通过指针串联在一起的线性结构,每个节点由两部分组成,一个是数据域,一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null.

链表的一般只给一个头节点head,通过这个头节点head我们就能遍历链表的每个节点. 节点我们一般采用一个类来表示,类成员变量有两个,一个基本数据类型data存值,一个引用数据类型next存下一个节点的指针. 微信截图_20241213182120.png

小贴士:

1)指针会指向一个内存地址,我们平常一个实例创建好返回给对象名的就是一个指针,这个指针指向这个实例的内存地址.

2)上面提到的对象名也就是我们常说的引用,这实际上可以看作一个变量,这个变量存的都是指针,也就是说引用是一种用来存指针的变量.

3)平常所说的,父类引用存储子类对象也就是引用是父类类型的,但是存的指针指向子类对象的.

4)总的来说,我们只要记住,引用是变量,指针是值.引用是用来存指针的变量,我们所有实例实际上都是通过指针来访问和使用的!

2.链表的类型

  • 单链表

这种就是单链表 微信截图_20241213182120.png

  • 双链表

这种就是双链表 微信截图_20241213183145.png

  • 循环链表

这种链表首尾相连,链表首尾相连,最后一位节点的引用不指向null而指向头节点head. 微信截图_20241213183434.png

3.链表的存储方式

由前面基本样貌的介绍,我们不难发现,链表在内存中存储不是连续的.因为这些节点实例在堆内存中不是连续的.

  1. 首先,创建多个节点实例,他们的内存是在堆内存里随意分配的,不会连着分配.

  2. 在获得这些节点实例的存着指针的引用后(因为引用就是一个变量,用引用给next引用赋值,就是将引用存着的指针赋给next),我们将它们的指针按顺序存在上一个节点的next引用中.

4.在Java中创建链表

public class ListNode {
    // 其实只定义成员变量也行
    int val;
    ListNode next;
    // 构造函数
    public ListNode(){
    }

    public ListNode(int val){
        this.val = val;
    }

    public ListNode(ListNode next){
        this.next = next;
    }

    public ListNode(int val, ListNode next){
        this.val = val;
        this.next = next;
    }
}

5.链表的操作

  • 删除节点

如图所示,比如我们要删除链表中的D节点,我们只需要让C节点的next引用存E节点的指针就可以跳过D节点,我们通过头节点head一路访问下去,用每个节点的指针获取下一个节点的指针. 微信截图_20241214101342.png 根据Java可达性原则,当我们不能在当前栈中的手段访问到D,那这个实例就会被释放.所以Java中我们不用手动释放内存.

  • 添加节点

如图所示,在C与D之间添加一个节点F,那就是让C.next存F的指针,我们直接用C.next就可以使用F节点,然后用F.next访问D,这样就相当于加了一个F节点在C和D中. 微信截图_20241214102556.png

6.性能分析

记住我们算时间复杂度时默认算的是最坏情况下的操作数. 微信截图_20241214103618.png

二.移除链表元素

三.设计链表

四.反转链表