当前位置: 首页 > news >正文

【数据结构】单链表核心知识点梳理

一、基本定义与结构

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。科普中国-单链表

1. 节点结构

单链表由节点串联而成,每个节点包含两部分:

  • 数据域:存储元素值(如整数、字符串等)
  • 指针域:通过引用(Java中)指向后继节点

Java节点类定义

public class ListNode {int val; // 数据域ListNode next; // 指针域(指向后继节点)// 构造方法public ListNode(int val) {this.val = val;this.next = null; // 初始后继节点为null}// get、set方法public int getVal() {return val;}public void setVal(int val) {this.val = val;}public ListNode getNext() {return next;}public void setNext(ListNode next) {this.next = next;}}

2. 头节点的作用

  • 带头节点:头节点不存储实际数据,其next指向首节点(第一个数据节点)。优势是统一插入/删除操作逻辑(无需特殊处理首节点),算法题中常用。

    // 带头节点的链表初始化
    ListNode head = new ListNode(-1); // 头节点(值无实际意义)
    
  • 不带头节点:首节点即第一个数据节点,操作首节点时需单独处理(如插入首节点需修改头指针),易出错,实际应用中较少使用。

二、创建方式

1. 头插法

  • 核心逻辑:新节点的next先指向头节点的后继,再将头节点的next指向新节点。
  • 特性:链表元素顺序与插入顺序相反(逆序),可直接用于链表逆置。

在这里插入图片描述

Java示例

    public static ListNode createByHeadInsert(int[] elements) {ListNode head = new ListNode(-1); // 头节点for (int val : elements) {ListNode newNode = new ListNode(val);newNode.setNext(head.getNext());head.setNext(newNode);}return head;}

数据流转过程如下:

  • 初始化头节点 :创建一个值为 -1 的头节点(哨兵节点),此时链表为空, head.getNext() 为 null

  • 遍历数组元素 :依次处理传入的每个元素值

  • 数据流转核心步骤 (以数组 [1,2,3] 为例):

  • 插入第一个元素 1 :

    • 创建新节点 newNode(1)
    • newNode.setNext(head.getNext()) → newNode.next = null
    • head.setNext(newNode) → head.next = newNode(1)
    • 链表状态:head(-1) -> 1 -> null
  • 插入第二个元素 2 :

    • 创建新节点 newNode(2)
    • newNode.setNext(head.getNext()) → newNode.next = 节点1
    • head.setNext(newNode) → head.next = newNode(2)
    • 链表状态:head(-1) -> 2 -> 1 -> null
  • 插入第三个元素 3 :

    • 创建新节点 newNode(3)
    • newNode.setNext(head.getNext()) → newNode.next = 节点2
    • head.setNext(newNode) → head.next = newNode(3)
    • 链表状态:head(-1) -> 3 -> 2 -> 1 -> null

2. 尾插法

  • 核心逻辑:用尾指针tail跟踪当前尾节点,每次将新节点连接到tail后,更新tail指向新节点。
  • 特性:链表元素顺序与插入顺序一致(正序)。
    在这里插入图片描述

Java示例

    public static ListNode createByTailInsert(int[] elements) {ListNode head = new ListNode(-1); // 头节点ListNode tail = head; // 尾指针初始指向头节点for (int val : elements) {ListNode newNode = new ListNode(val);tail.setNext(newNode);tail = newNode;}tail.setNext(null);return head;}
  • 初始化阶段 :

    • 创建一个值为 -1 的头节点(哨兵节点)
    • 将尾指针 tail 初始指向头节点
    • 此时链表为空, head.getNext() 和 tail.getNext() 都为 null
  • 遍历数组元素 :依次处理传入的每个元素值

  • 数据流转核心步骤 (以数组 [1,2,3] 为例):

    • 插入第一个元素 1 :

      • 创建新节点 newNode(1)
      • tail.setNext(newNode) → 此时 tail 指向 head,所以 head.next = newNode(1)
      • tail = newNode → 尾指针移动到新节点1
      • 链表状态:head(-1) -> 1 -> null
    • 插入第二个元素 2 :

      • 创建新节点 newNode(2)
      • tail.setNext(newNode) → 此时 tail 指向节点1,所以 1.next = newNode(2)
      • tail = newNode → 尾指针移动到新节点2
      • 链表状态:head(-1) -> 1 -> 2 -> null
    • 插入第三个元素 3 :

      • 创建新节点 newNode(3)
      • tail.setNext(newNode) → 此时 tail 指向节点2,所以 2.next = newNode(3)
      • tail = newNode → 尾指针移动到新节点3
      • 链表状态:head(-1) -> 1 -> 2 -> 3 -> null
  • 收尾处理 :

    • 设置尾节点的 next 为 null: tail.setNext(null)

三、基本操作

1. 插入操作

  • 场景:在节点p后插入新节点newNode
  • 步骤(顺序不可颠倒):
    1. newNode.next = p.next(新节点先连接p的后继)// newNode.setNext(p.getNext());
    2. p.next = newNodep再指向新节点)// p.setNext(newNode);

在这里插入图片描述

Java示例

代码中用的是get,set方法(请看标题:1. 节点结构 中的内容),代码中没用.next什么的,get,set看着更舒服(我感觉)

    public static void insertAfter(ListNode p, int val) {if (p == null) return;ListNode newNode = new ListNode(val);newNode.setNext(p.getNext());p.setNext(newNode);}

2. 删除操作

  • 场景:删除节点p的后继节点。
  • 步骤
    1. 找到待删节点的前驱p
    2. p.next = p.next.nextp直接指向待删节点的后继,跳过待删节点)
    3. (Java中无需手动释放内存,由GC自动回收)

在这里插入图片描述
【鉴于个人视角的有限性,所述观点未必全面,欢迎理性探讨与指正】

节点2指向节点3的引用(“2到3这条线”)暂时依然存在,但由于节点2不再被链表中的任何其他节点引用,它变成了一个孤立节点

当JVM的垃圾回收器检测到节点2不再被任何活动引用指向时,会将其标记为可回收

最终在垃圾回收过程中,节点2占用的内存会被释放

节点2内部的所有引用(包括它指向节点3的引用)也会一并消失

所以最后2到3这条线没了

Java示例

代码中用的是getset方法(请看标题:1. 节点结构 中的内容)

    public static void deleteAfter(ListNode p) {if (p == null || p.getNext() == null) return;p.setNext(p.getNext().getNext());}

本文内容仅供参考,不构成任何形式的专业建议。作者尽力确保信息的准确性,但不对因使用本文内容而引发的任何直接或间接损失负责。读者应自行核实信息并咨询相关专业人士。

http://www.dtcms.com/a/598183.html

相关文章:

  • 中山做网站排名国外中文网站域名注册商
  • 在 LangFlow 中,**节点(Node)是构成工作流的核心基本单元**
  • 普中51单片机学习笔记-数码管
  • Python 开发环境安装与配置全指南(2025版)
  • 上海建设官方网站设计学类包括哪些专业
  • 网站 网页制作南京广告公司黄页
  • 如何用网站做推广网络营销策划书封面
  • 宁波seo建站价格wordpress长文章分页代码
  • AI 赋能教育新生态 | 教学创新、范式转型与实践路径探析
  • 网站开发按钮素材搜索视频 网站开发
  • 二手车网站开发多少钱网站里的课程配图怎么做
  • 网站上传模板后太原制作网站的公司
  • 【复习408】计算机网络应用层协议详解
  • 在那些网站做宣传更好wordpress怎么安装上服务器
  • 2023年php凉透了大连seo顾问
  • Redis的知识整理《1》
  • 怎样免费建一个网站网站开发培训费用
  • 数据产品之数据埋点
  • 7.MySQL这的内置函数
  • 网站建设设计师招募重庆网络seo公司
  • -1网站建设购物中心网站建设
  • 量子计算自学记录
  • 儿童网站建设网站建设要考虑哪些内容
  • office online server
  • 【 Git:本地项目上传至 Gitee 仓库】
  • Hello-Agents task2 大语言模型基础
  • 机器学习“开箱即用“:Scikit-learn快速入门指南
  • 乐迪信息:智慧煤矿井下安全:AI 摄像机实时抓拍违规行为
  • 重庆免费自助建站模板电影网站制作模板
  • 轻松筹 做的网站价格网站建设赠送seo