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

链表的探索研究

链表的定义

链表是一种 线性数据结构,和数组一样存储一组元素。

区别:

数组:内存连续,随机访问 O(1),但插入/删除成本高 O(n)。

链表:内存不连续,依靠指针连接,插入/删除 O(1),但访问某个位置 O(n)。

链表的分类

1. 按指针方向分类

单向链表(Singly Linked List)

每个节点只有一个指针 next,指向下一个节点。只能从头到尾遍历。

优点:结构简单,内存消耗少。

缺点:不能反向遍历,删除/插入需要找到前驱节点。

class Node {int val;Node next;
}
//单向链表(Singly Linked List)
//每个节点只保存 next 指针,指向下一个节点。
//无法从后往前遍历。class ListNode {int val;ListNode next;ListNode(int val) {this.val = val;}
}

双向链表(Doubly Linked List)

每个节点有两个指针:prev 和 next,分别指向前后节点。可以双向遍历。插入、删除更灵活,但多占用一个指针空间。

class DNode {int val;DNode prev, next;
}

//双向链表(Doubly Linked List)
//节点有两个指针:prev 和 next,可双向遍历。
//插入/删除更灵活,但需要更多内存。
class DNode {int val;DNode prev, next;DNode(int val) {this.val = val;}
}

2. 按首尾是否相连分类

非循环链表:

  • 尾节点的 next 指针为 null。
  • 最常见的链表形式。

循环链表(Circular Linked List):

  • 尾节点的 next 指向头节点,形成环。
  • 可以从任意节点出发遍历整个链表。
  • 可用于 约瑟夫环、循环队列 等问题。
  • 尾节点指向头节点
tail.next = head;

按节点存储数据数量分类

单元素链表节点

  • 每个节点只存储一个数据。

多元素链表节点(不常用)

  • 每个节点可存储多个数据元素,类似“块状链表”,在某些场景(比如内存优化)会用到。

静态链表

  • 不使用指针,而是用数组下标表示 next。
  • 常用于不能动态分配内存的语言(如 C 语言中的结构体 + 数组)。

跳表(Skip List)

  • 本质是多层链表,每一层是下层的“索引”。
  • 通过跳跃访问加快查找速度,查找效率接近二分查找。

LinkedList

Java 标准库中的 LinkedList

Java 提供了现成的 java.util.LinkedList,底层是 双向链表。

特点:

  1. 实现了 List、Deque 接口。
  2. 插入、删除效率高。
  3. 不支持随机访问(不像 ArrayList 的 O(1))。

常用方法:


LinkedList<Integer> list = new LinkedList<>();
list.add(10);         // 尾插
list.addFirst(5);     // 头插
list.addLast(20);     // 尾插
list.removeFirst();   // 删除头
list.removeLast();    // 删除尾
list.get(0);          // 访问第一个元素 (O(n))
  1. 链表的基本操作(手写实现)
    ① 头插法
public void addFirst(int val) {ListNode node = new ListNode(val);node.next = head;head = node;
}

② 尾插法

public void addLast(int val) {ListNode node = new ListNode(val);if (head == null) {head = node;return;}ListNode cur = head;while (cur.next != null) {cur = cur.next;}cur.next = node;
}

③ 删除节点

public void remove(int val) {if (head == null) return;if (head.val == val) {head = head.next;return;}ListNode cur = head;while (cur.next != null) {if (cur.next.val == val) {cur.next = cur.next.next;return;}cur = cur.next;}
}

④ 查找节点

public boolean contains(int val) {ListNode cur = head;while (cur != null) {if (cur.val == val) return true;cur = cur.next;}return false;
}
  1. 链表常见题型(面试高频)
反转链表public ListNode reverseList(ListNode head) {ListNode prev = null;ListNode cur = head;while (cur != null) {ListNode next = cur.next;cur.next = prev;prev = cur;cur = next;}return prev;
}

寻找链表中间节点(快慢指针)

public ListNode middleNode(ListNode head) {ListNode slow = head, fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}return slow;
}

检测环形链表(Floyd 判圈法)

public boolean hasCycle(ListNode head) {ListNode slow = head, fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;if (slow == fast) return true;}return false;
}

合并两个有序链表


public ListNode mergeTwoLists(ListNode l1, ListNode l2) {ListNode dummy = new ListNode(-1);ListNode cur = dummy;while (l1 != null && l2 != null) {if (l1.val < l2.val) {cur.next = l1;l1 = l1.next;} else {cur.next = l2;l2 = l2.next;}cur = cur.next;}cur.next = (l1 != null) ? l1 : l2;return dummy.next;
}
http://www.dtcms.com/a/394179.html

相关文章:

  • 2025年工程项目管理软件全面测评
  • JAVA算法练习题day17
  • Nacos:服务注册和配置中心
  • Linux 命令行快捷键
  • EasyClick JavaScript Number
  • LeetCode:42.将有序数组转化为二叉搜索树
  • 海外代理IP网站有哪些?高并发场景海外代理IP服务支持平台
  • JavaScript数据交互
  • 11.2.5 自定义聊天室
  • 力扣:字母异味词分组
  • Linux视频学习笔记
  • 2014/12 JLPT听力原文 问题四
  • Elasticsearch面试精讲 Day 21:地理位置搜索与空间查询
  • 华为数字化实战指南:从顶层设计到行业落地的系统方法论
  • 外部 Tomcat 部署详细
  • 【回文数猜想】2022-11-9
  • 216. 组合总和 III
  • Bugku-请攻击这个压缩包
  • 2. NumPy数组属性详解:形状、维度与数据类型
  • 【css特效】:实现背景色跟随图片相近色处理
  • vuex原理
  • 内存泄露怎么排查?
  • nginx配置防盗链入门
  • Kafka 多机房、跨集群复制、多租户、硬件与操作系统、全栈监控
  • leetcode136.只出现一次的数字
  • 力扣hot100:环形链表II(哈希算法与快慢指针法思路讲解)
  • 【算法】【Leetcode】【数学】统计1的个数 数位统计法
  • Kafka面试精讲 Day 21:Kafka Connect数据集成
  • MySQL 主从复制完整配置指南
  • 力扣每日一刷Day 23