数据结构——链表

目录

一、链表

1、单向链表

单向链表的遍历方式:

2、循环链表

3、双向链表

二、自行车停放(双向链表)


 

一、链表

  •  链表是由许多相同数据类型的数据项按特定顺序排列而成的线性表
  • 特性:存放的位置是不连续且随机的,动态分配内存
    • 内存泄漏(Memory Leak):变量使用了内存存放,使用后,没有释放内存
  • 优点:插入或删除数据方便
  • 缺点:查找不方便,要按序查找数据
  • Java中常见的链表实现类:
    • LinkedList 
      • 基于链表实现,插入和删除操作时间复杂度为 O(1),因为只需修改节点的指针。
      • 不支持随机访问,需要从头部或尾部开始遍历链表以访问特定位置的元素,时间复杂度为 O(n)。
      • 可存储相同的元素
      • 增删元素后,链表里的元素下标不会发生变化
      • 适用于插入删除操作频繁、读取操作相对较少的场景。另外,LinkedList还可以作为队列或栈来使用。
    • ArrayList 

      • 基于数组实现,支持随机访问,根据索引可以在 O(1) 的时间复杂度内访问元素。
      • 插入和删除操作需要移动元素,时间复杂度为 O(n)。如果在末尾插入或删除元素,时间复杂度为 O(1)。
      • 增删元素后,会自动调整链表里元素的下标
      • 适用于读取操作频繁、插入删除操作相对较少的场景。
    • ListNode 则是自定义节点类,通常用于手动实现链表结构。

1、单向链表

  • 单向链表是一种数据结构,其中的每个节点包含数据和一个指向下一个节点的引用。
  • 链表的第一个节点称为头节点,最后一个节点的引用指向 null。这意味着在单向链表中,只能从头节点开始,按顺序遍历到最后一个节点,而无法逆向遍历。

单向链表的示例代码:

// 定义链表节点,包含节点数据和指向下一个节点的引用
class Node {int data;Node next;// 节点构造函数public Node(int data) {this.data = data;this.next = null;}
}// 定义链表
class LinkedList {Node head;// 链表构造函数public LinkedList() {this.head = null;}// 在链表末尾添加节点public void append(int data) {Node newNode = new Node(data);if (head == null) {head = newNode;} else {Node current = head;while (current.next != null) {current = current.next;}current.next = newNode;}}// 删除特定数值节点public void delete(int data) {if (head == null) {return;}if (head.data == data) {head = head.next;return;}Node current = head;while (current.next != null) {if (current.next.data == data) {current.next = current.next.next;return;}current = current.next;}}// 打印链表public void printList() {Node current = head;while (current != null) {System.out.print(current.data + " ");current = current.next;}System.out.println();}
}

单向链表的遍历方式:

在 Java 中,可以使用不同的方法来遍历 List。以下是几种常用的遍历方法:

1. 使用 for 循环:

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");for (int i = 0; i < list.size(); i++) {String element = list.get(i);System.out.println(element);
}

2. 使用增强型 for 循环(foreach 循环):

for (String element : list) {System.out.println(element);
}

3. 使用迭代器(Iterator):

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {String element = iterator.next();System.out.println(element);
}

2、循环链表

  • 循环链表和普通链表的区别在于循环链表的末尾节点指向链表的头部节点,形成一个环形结构。这种特殊的连接方式使得循环链表可以无限地往后遍历下去,直到再次经过链表的起始节点。

  • 循环链表可以是单向的,也可以是双向的,它们在实际应用中通常用于模拟循环队列或者循环缓冲区等结构。

  • 在循环链表中,基本的节点结构和普通链表一样,每个节点包含一个数据域和一个指向下一个节点的指针。

  • 循环链表通常具有一些特殊的操作,比如判断链表是否为空、遍历链表的方法等,这些操作和普通链表有所不同。在实际编程中,设计和操作循环链表需要特别注意避免陷入无限循环的情况。

循环链表的示例代码:

// 定义循环链表节点类
class ListNode {int val;ListNode next;// 节点类的构造函数ListNode(int val) {this.val = val;this.next = null;}
}// 定义循环链表类
class CircularLinkedList {private ListNode tail;  // 循环链表的尾节点// 添加节点到循环链表尾部public void addToTail(int value) {ListNode newNode = new ListNode(value);if (tail == null) {tail = newNode;tail.next = tail;  // 只有一个节点时,让节点指向自己形成循环} else {newNode.next = tail.next;  // 新节点指向头节点tail.next = newNode;       // 原尾节点指向新节点tail = newNode;            // 更新尾节点为新节点}}// 从循环链表中删除指定数值的节点public void deleteNode(int value) {if (tail != null) {ListNode current = tail;while (current.next != tail) {if (current.next.val == value) {current.next = current.next.next;  // 绕过匹配节点return;}current = current.next;}// 当只有一个节点时需要特殊处理if (tail.val == value) {if (tail == tail.next) {tail = null;  // 移除最后一个节点} else {tail.next = tail.next.next;  // 只有一个节点时删除自身}}}}// 遍历循环链表并打印节点数值public void printList() {if (tail != null) {ListNode current = tail.next;  // 头节点do {System.out.print(current.val + " ");current = current.next;} while (current != tail.next);}System.out.println();}
}

3、双向链表

  • 双向链表是一种数据结构,它由多个节点组成。
  • 每个节点包含两个指针,一个指向前一个节点,另一个指向后一个节点。这使得在双向链表中,每个节点都可以直接访问其前一个节点和后一个节点。
  • 双向链表相对于单向链表的优势在于可以双向遍历链表,可以在 O(1) 时间复杂度内实现在任意位置插入和删除节点。

双向链表的示例代码:

//双向链表节点的定义,每个节点包含一个整数值和两个指针,分别指向前一个节点和后一个节点。
class ListNode {int val;ListNode prev;ListNode next;// 构造函数ListNode(int val) {this.val = val;this.prev = null;this.next = null;}
}class DoublyLinkedList {ListNode head;// 在链表头部插入节点void insertAtHead(int val) {ListNode newHead = new ListNode(val);if (head != null) {newHead.next = head;head.prev = newHead;}head = newHead;}// 在链表尾部插入节点void insertAtTail(int val) {ListNode newTail = new ListNode(val);if (head == null) {head = newTail;return;}ListNode current = head;while (current.next != null) {current = current.next;}current.next = newTail;newTail.prev = current;}// 删除指定数值的节点void deleteNode(int val) {ListNode current = head;while (current != null) {if (current.val == val) {if (current.prev != null) {current.prev.next = current.next;} else {head = current.next;}if (current.next != null) {current.next.prev = current.prev;}return;}current = current.next;}}
}

二、自行车停放(双向链表)

分析:

  •  如果用单向链表,当n较大时,运行会超时
package no1_1;
import java.util.*;public class Main {public static class TreeNode {int left;int right;}public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 读取输入的值 n 和 kint n = sc.nextInt();TreeNode[] node = new TreeNode[100000 + 2];int k = sc.nextInt();// 初始化节点数组for (int i = 0; i <= 100001; i++) {node[i] = new TreeNode();node[i].left = -1;node[i].right = -1;}// 构建链表结构node[k].left = 0;node[k].right = 100001;node[0].right = k;node[n + 1].left = k;// 读取边的信息,构建链表for (int i = 0; i < n - 1; i++) {int x = sc.nextInt();int y = sc.nextInt();int z = sc.nextInt();if (z == 0) {// 在 y 的左边插入节点 xnode[x].left = node[y].left;node[x].right = y;node[node[y].left].right = x;node[y].left = x;} else {// 在 y 的右边插入节点 xnode[x].right = node[y].right;node[x].left = y;node[node[y].right].left = x;node[y].right = x;}}// 遍历链表并输出结果int index = 0;for (;;) {if (node[index].right == 100001) break;System.out.print(node[index].right + " ");index = node[index].right;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/300823.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全坚固笔记本丨工业笔记本丨三防笔记本相较于普通笔记本有哪些优势?

三防笔记本和普通笔记本在设计和性能方面存在显著差异&#xff0c;三防笔记本相较于普通笔记本具备以下优势&#xff1a; 三防笔记本通常采用耐磨、耐摔的材料&#xff0c;并具有坚固的外壳设计&#xff0c;能够承受恶劣环境和意外碰撞&#xff0c;有效保护内部组件不受损坏。相…

armlinux裸机-uart

uart是一对一的串行异步全双工通信通信协议&#xff0c;串行速度较慢&#xff08;usart支持同步通信&#xff09; 传输原理 多个参数可以设置 为满足使用需求&#xff0c;我们一般都用带fifo缓冲中断。 我们使用S3C2440芯片&#xff0c;具体寄存器操作可以查看用户手册

NOI - OpenJudge - 2.5基本算法之搜索 - 1490:A Knight‘s Journey - 超详解析(含AC代码)

点赞关注吧~ 1490:A Knights Journey 查看提交统计提问 总时间限制: 1000ms 内存限制: 65536kB 描述 Background The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey around the world. When…

【WEEK6】 【DAY7】MD5 Encryption Transactions【English Version】

2024.4.7 Sunday Following the previous article 【WEEK6】 【DAY3】MySQL Functions【English Version】 Contents 5.3. MD5 Encryption5.3.1. Introduction5.3.2. Testing MD5 Encryption5.3.2.1. Plain Text Passwords5.3.2.2. Implementing Data Encryption5.3.2.3. Encry…

实景三维在文化旅游领域的应用

实景三维技术&#xff0c;作为一种前沿的科技手段&#xff0c;近年来在文化旅游领域的应用逐渐崭露头角。它能够将真实世界的场景以三维的形式精确呈现&#xff0c;为游客带来身临其境的体验&#xff0c;为文化旅游注入新的活力。本文将探讨实景三维在文化旅游领域的应用及其所…

npm版本切换工具nvm

有了nvm&#xff0c;可以在一台机器上同时安装多个版本的nodejs&#xff0c;然后指定使用某个版本。 前端开发的时候&#xff0c;安装依赖一直是个令我头痛的问题。总是报错&#xff0c;或者不是少了这样就是少了那样&#xff0c;鸡飞狗走。以往&#xff0c;一般要装个enpm&am…

【java的本地锁到分布式锁介绍】

文章目录 1.java本地自带锁介绍及应用synchronized&#xff08;1&#xff09;synchronized原理和优化&#xff08;2&#xff09;synchronized作用&#xff08;3&#xff09;synchronized的使用 CAS(1) CAS原理&#xff08;2&#xff09;CAS和synchronized优缺点 lock 2.分布式锁…

基于Spring Boot的网上书城系统(带文档)

主要功能 本次设计任务是要设计一个网上书城管理系统&#xff0c;通过这个系统能够满足网上书城的管理及用户的图书信息管理及购物功能。系统的主要功能包括&#xff1a;首页、个人中心、用户管理、图书类型管理、图书分类管理、图书信息管理、我的收藏管理、系统管理、订单管…

c++的学习之路:14、list(1)

本章讲一下如何使用list&#xff0c;代码在文章末 目录 一、list介绍 二、增 三、删 四、查和改 五、交换 六、代码 一、list介绍 首先还是看一看官方文档的介绍如下图&#xff0c;如下方五点&#xff1a; 1. list是可以在常数范围内在任意位置进行插入和删除的序列式…

面向电力行业定制安全云工作站解决方案,麒麟信安出席2024年电力企业信创替代技术研讨会

日前&#xff0c;由中国电子企业协会主办的“2024年电力企业信创替代技术研讨会”在江苏南京正式召开。会议以国家推进实现自主可控、加快建设“数字中国”为大背景&#xff0c;聚焦电力企业紧抓“信创替代”机遇&#xff0c;通过安全可靠的软硬件迭代升级&#xff0c;实现企业…

2024年妈妈杯数学建模MathorCup数学建模思路B题思路解析+参考成品

1 赛题思路 (赛题出来以后第一时间在群内分享&#xff0c;点击下方群名片即可加群) 2 比赛日期和时间 报名截止时间&#xff1a;2024年4月11日&#xff08;周四&#xff09;12:00 比赛开始时间&#xff1a;2024年4月12日&#xff08;周五&#xff09;8:00 比赛结束时间&…

milvus search api的数据结构

search api的数据结构 此api的功能是向量相似度搜索(vector similarity search) 一个完整的search例子: 服务端collection是一个hnsw类型的索引。 import random from pymilvus import (connections,Collection, )dim 128if __name__ __main__:connections.connect(alias…

【go】模板展示不同k8s命名空间的deployment

gin模板展示k8s命名空间的资源 这里学习如何在前端单页面&#xff0c;调用后端接口展示k8s的资源 技术栈 后端 -> go -> gin -> gin模板前端 -> gin模板 -> html jsk8s -> k8s-go-client &#xff0c;基本资源(deployment等) 环境 go 1.19k8s 1.23go m…

面向低碳经济运行目标的多微网能量互联优化调度matlab程序

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 运用平台 matlabgurobi 程序简介 该程序为多微网协同优化调度模型&#xff0c;系统在保障综合效益的基础上&#xff0c;调度时优先协调微网与微网之间的能量流动&#xff0c;将与大电网的互联交互作为备用…

ES学习笔记01

1.ES安装 下载地址&#xff1a; es官网下载 这里使用的是7.8.0的版本信息 下载完成后解压即可完成安装 2.启动运行 点击bin目录下的elasticsearch.bat文件即可启动 在浏览器中输入localhost:9200显示如下&#xff1a; 在路径中加入对应访问后缀即可访问对应信息 如&#…

c++11 标准模板(STL)本地化库 - 平面类别 - (std::ctype) 定义字符分类表(七)

本地化库 本地环境设施包含字符分类和字符串校对、数值、货币及日期/时间格式化和分析&#xff0c;以及消息取得的国际化支持。本地环境设置控制流 I/O 、正则表达式库和 C 标准库的其他组件的行为。 平面类别 定义字符分类表 std::ctype template< class CharT > clas…

HiveSQL如何生成连续日期剖析

HiveSQL如何生成连续日期剖析 情景假设&#xff1a; 有一结果表&#xff0c;表中有start_dt和end_dt两个字段&#xff0c;&#xff0c;想要根据开始和结束时间生成连续日期的多条数据&#xff0c;应该怎么做&#xff1f;直接上结果sql。&#xff08;为了便于演示和测试这里通过…

lua学习笔记9(字典的学习)

print("********************字典的学习***********************") a{["凌少"]"傻逼",["我"]"天才",["age"]24,["daihao"]114514,["8848"]20000} --访问单个变量 print(a["凌少"])…

社交媒体市场:揭示Facebook的商业模式

在数字化时代&#xff0c;社交媒体已经成为人们生活中不可或缺的一部分。Facebook作为全球最大的社交媒体平台之一&#xff0c;其商业模式的运作方式对于了解社交媒体市场的发展趋势和影响力至关重要。本文将深入探讨Facebook的商业模式&#xff0c;剖析其运作机制&#xff0c;…

hadoop分布式计算组件

什么是计算、分布式计算&#xff1f; 计算&#xff1a;对数据进行处理&#xff0c;使用统计分析等手段得到需要的结果 分布式计算&#xff1a;多台服务器协同工作&#xff0c;共同完成一个计算任务 分布式计算常见的2种工作模式 分散->汇总(MapReduce就是这种模式)中心调…