Java——LinkedList

1、链表

1.1 链表的概念及结构

链表在逻辑层面上是连续的,在物理层面上不一定是连续的

链表结构可分为,单向或双向、带头或不带头、循环或非循环,组合共计8种

重点:无头单向非循环链表、无头双向链表

1.2 模拟实现无头单向非循环链表

一个链表由若干节点组成,结合 内部类 知识,可将节点类定义在链表类中,成为内部类

public class MySingleLinkedList {static class ListNode {//该内部类中定义的是节点的属性public int val;public ListNode next;public ListNode(int val) {this.val = val;}}public ListNode head;//链表的头节点,定义在MySingleLinkedList类中}

下面以穷举的方式创建链表方便理解(真正创建链表并非如此)

//MySingleLinkedList类//该方法创建一个链表,头节点为node1,当该方法结束后,变量node1...都会销毁,只剩下头节点为head的链表public void createdList(){ListNode node1 = new ListNode(1);ListNode node2 = new ListNode(2);ListNode node3 = new ListNode(3);ListNode node4 = new ListNode(4);ListNode node5 = new ListNode(5);node1.next = node2;node2.next = node3;node3.next = node4;node4.next = node5;this.head = node1;}

打印链表

//MySingleLinkedList 类public void display() {ListNode cur = head; //若直接使用head进行遍历打印,将只能打印一次,再次调用该函数,头节点就不在原来的位置了while(cur != null) { //注意!此处若写成 cur.next != null 则不会打印最后一个节点System.out.print(cur.val + " ");cur = cur.next;}}

求链表长度:

    //遍历即可public int size() {ListNode cur = head;int count = 0;while(cur != null) {cur = cur.next;count++;}return count;}

头插法:

    public void addFirst(int data) {ListNode newNode = new ListNode(data);newNode.next = head;head = newNode;}

尾插法:

    public void addLast(int data) {ListNode newNode = new ListNode(data);//不要忘记:判空!if(head == null) {head = newNode;return;}ListNode cur = head;while(cur.next != null) { //此处若写成 cur.next != null 则不会打印最后一个节点cur = cur.next;}cur.next = newNode;}

在index位置插入

// IndexNotLegalException 异常类
public class IndexNotLegalException extends RuntimeException{public IndexNotLegalException() {}public IndexNotLegalException(String msg) {super(msg);}
}// MySingleLinkedList 类public void addIndex(int index, int data) {//1、判断index合法性try{checkIndex(index);}catch(IndexNotLegalException e) {e.printStackTrace();}//2、index == 0 || index == size()if(index == 0) {addFirst(data);return;}if(index == size()) {addLast(data);return;}//3、找到index的前一个位置ListNode cur = findIndexSubOne(index);//4、进行连接ListNode node = new ListNode(data);node.next = cur.next;cur.next = node;}private void checkIndex(int index) throws IndexNotLegalException{if(index < 0 || index > size()) {throw new IndexNotLegalException("index不合法!");}}private ListNode findIndexSubOne(int index) {int count = 0;ListNode cur = head;while(count < index-1) {cur = cur.next;count++;}return cur;}

查找关键字key是否包含在链表中

    public boolean contains(int key) {ListNode cur = head;while(cur != null) {if(cur.val == key) {return true;}cur = cur.next;}return false;}

删除第一次出现关键字key的节点

    public void remove(int key) {//判空if(head == null) {return;}//若头节点为keywhile(head.val == key) {head = head.next;return;}ListNode cur = head;//遍历找到值为key的节点while(cur.next != null) {if(cur.next.val == key) {cur.next = cur.next.next;return;}cur = cur.next;}System.out.println("没有找到要删除的数字!");}

删除所有值为key的节点

    public void removeAllKey(int key) {//判空if (this.head == null) {return;}//快慢指针ListNode prev = head;ListNode cur = head.next;while(cur != null) {if(cur.val == key) {prev.next = cur.next;}else {prev = cur;}cur = cur.next;}//处理头节点,当上述操作完成后,只剩下头节点没有判断//该方法优于一上来就判断头节点if(head.val == key) {head =head.next;}}

清空链表

    public void clear() {ListNode cur = head;while(cur != null) {ListNode curN = cur.next;cur.next = null;cur = curN;}head = null;}

1.3 模拟实现无头双向非循环链表

public class MyLinkedList {static class ListNode {public int data;public ListNode prev;//前驱节点public ListNode next;//后继节点public ListNode(int data){this.data = data;}}public ListNode head;//头节点public ListNode last;//尾节点//得到单链表的长度public int size(){int count = 0;ListNode cur = head;while(cur != null) {count++;cur = cur.next;}return count;}public void display(){ListNode cur = head;while(cur != null) {System.out.print(cur.data + " ");cur = cur.next;}System.out.println();}//查找是否包含关键字key是否在单链表当中public boolean contains(int key){ListNode cur = head;while(cur != null) {if(cur.data == key) {return true;}cur = cur.next;}return false;}//头插法public void addFirst(int data){ListNode node = new ListNode(data);if(head == null) {head = last = node;}else {head.prev = node;node.next = head;head = node;}}//尾插法public void addLast(int data){ListNode node = new ListNode(data);if(head == null) {head = last = node;}else {last.next = node;node.prev = last;last = node;}}//任意位置插入,第一个数据节点为0号下标public void addIndex(int index,int data){try{checkIndex(index);}catch(IndexIllegalException e) {e.printStackTrace();}if(index == 0) {addFirst(data);return;}if(index == size()) {addLast(data);return;}ListNode node = new ListNode(data);ListNode cur = findIndex(index);node.next = cur;node.prev = cur.prev;cur.prev.next = node;cur.prev = node;}private ListNode findIndex(int index) {ListNode cur = head;while(index != 0) {cur = cur.next;index--;}return cur;}private void checkIndex(int index) throws IndexIllegalException{if(index < 0 || index > size()) {throw new IndexIllegalException("双向链表index不合法!");}}//删除第一次出现关键字为key的节点public void remove(int key){ListNode cur = head;while(cur != null) {if(cur.data == key) {if(cur == head) {head = head.next;if(head != null) {head.prev = null;}else {last = null;}}else if(cur == last) {cur.prev.next = null;last = cur.prev;}else {cur.prev.next = cur.next;cur.next.prev = cur.prev;}return;}cur = cur.next;}}//删除所有值为key的节点public void removeAllKey(int key){ListNode cur = head;while(cur != null) {if(cur.data == key) {if(cur == head) {head = head.next;if(head != null) {head.prev = null;}else {last = null;}}else if(cur == last) {cur.prev.next = null;last = cur.prev;}else {cur.prev.next = cur.next;cur.next.prev = cur.prev;}}cur = cur.next;}}public void clear(){ListNode cur = head.next;while(cur != null) {cur = head.next;head.prev = null;head.next = null;head = cur;}head = last = null;}
}

链表遍历方式:

    public static void main(String[] args) {LinkedList<Integer> list = new LinkedList<>();list.add(1);list.add(2);list.add(3);//直接sout打印System.out.println(list);System.out.println("======");//foreatch循环打印for(Integer x : list) {System.out.print(x + " ");}System.out.println();System.out.println("======");//for循环打印for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i) + " ");}System.out.println();System.out.println("======");//Iterator打印Iterator<Integer> it = list.iterator();while(it.hasNext()) {System.out.print(it.next() + " ");}System.out.println();System.out.println("======");//ListIterator可以倒着打印ListIterator<Integer> it3 = list.listIterator(list.size());while(it3.hasPrevious()) {System.out.print(it3.previous() + " ");}}

运行结果:

2、ArrayList 和 LinkedList 的区别

不同点ArrayListLinkedList
存储空间上逻辑&物理均连续逻辑上连续,物理上不一定连续
随机访问支持,时间复杂度为O(1)不支持,时间复杂度为O(N)
头插需要搬运元素,O(N)只需修改引用的指向,O(1)
插入空间不够时需要扩容没有容量概念
应用场景元素高效存储+频繁访问频繁在任意位置插入删除操作

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

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

相关文章

拥抱开源,构建未来:王嘉树与 TDengine 的开源之旅

在当代的技术浪潮中&#xff0c;开源文化不仅催生了无数创新技术&#xff0c;也为广大技术爱好者提供了一个展示才华、相互学习的平台。我们今天采访到的这位北京邮电大学电子工程学院的研究生&#xff0c;就是在这样的背景下&#xff0c;通过开源活动不断探索、学习并实现自我…

数据分析常用6种分析思路(下)

作为一名数据分析师&#xff0c;你又没有发现&#xff0c;自己经常碰到一些棘手的问题就没有思路&#xff0c;甚至怀疑自己究竟有没有好好学过分析&#xff1f; 在上篇文章里&#xff0c;我们讲到了数据分析中的流程、分类、对比三大块&#xff0c;今天&#xff0c;我们继续讲…

【ElasticSearch】windows server 2019安装ES8.9.1 + kibana8.9.1 + IK分词器

目录 准备工作 ES Kibana IK 安装 es es访问测试 将es安装为系统服务 Kibana 配置es 运行kibana 访问测试 IK 补充 准备工作 ES8.9.1 kibana8.9.1 IK的版本最好要对应上&#xff01;&#xff01;&#xff01; ES es8.9.1&#xff1a; https://artifa…

笔记 | 用go写个docker

仅作为自己学习过程的记录&#xff0c;不具备参考价值 前言 看到一段非常有意思的话&#xff1a; 很多人刚接触docker的时候就会感觉非常神奇&#xff0c;感觉这个技术非常新颖&#xff0c;其实并不然&#xff0c;docker使用到的技术都是之前已经存在过的&#xff0c;只不过旧…

操作系统——信号

将信号分为以上四个阶段 1.信号注册&#xff1a;是针对信号处理方式的规定&#xff0c;进程收到信号时有三种处理方式&#xff1a;默认动作&#xff0c;忽略&#xff0c;自定义动作。如果不是自定义动作&#xff0c;这一步可以忽略。这个步骤要使用到signal/sigaction接口 2.…

5. 条件和递归

5. 条件和递归 本章主要话题是if表达式, 它根据程序的状态执行不同的代码. 但首先介绍两个操作符号: 向下取整除法操作符和求模操作符.5.1 向下取整除法操作符和求模操作符 向下取整除法操作符(//)对两个数除法运算, 并向下取整得到一个整数. 假设, 一个电影的播放时长为105分…

Java | Leetcode Java题解之第150题逆波兰表达式求值

题目&#xff1a; 题解&#xff1a; class Solution {public int evalRPN(String[] tokens) {int n tokens.length;int[] stack new int[(n 1) / 2];int index -1;for (int i 0; i < n; i) {String token tokens[i];switch (token) {case "":index--;stack…

vi/vim使用命令

你是否在编辑文件时以为键盘坏了&#xff0c;为什么不能删除呢&#xff0c;为什么不能敲代码呢&#xff0c;等你初识vi&#xff0c;会觉得这个东西为什么设计得这么难用&#xff0c;这篇教程带你熟练得用上这款经典的工具 Vi 是在 Unix 系统上广泛使用的编辑器&#xff0c;Vim …

Unity与Js通信交互

目录 1.Js给Unity传递消息 2.Unity给Js传递消息 简介: Unity 与 JavaScript 通信交互是指在 Unity 项目中实现与 JavaScript 代码进行数据交换和功能调用的过程。 在 Unity 中&#xff0c;可以通过特定的接口和技术来与外部的 JavaScript 环境进行连接。这使得 Unity 能够利…

进击算法工程师深度学习课程

"进击算法工程师深度学习课程"旨在培养学员在深度学习领域的专业技能和实战经验。课程涵盖深度学习基础理论、神经网络架构、模型优化方法等内容&#xff0c;通过项目实践和算法实现&#xff0c;帮助学员掌握深度学习算法原理和应用&#xff0c;提升在算法工程师领域…

EasyExcel文件导出,出现有文件但没有数据的问题

一开始由于JDK版本过高&#xff0c;我用的17&#xff0c;一直excel没有数据&#xff0c;表头也没有&#xff0c;后来摸索了好久&#xff0c;找了资料也没有&#xff0c;后来改了代码后报了一个错误&#xff08;com.alibaba.excel.exception.ExcelGenerateException: java.lang.…

【抽代复习笔记】19-群(十三):奇偶置换、循环置换的几个定理及例题

定义&#xff1a; ①在Sn中&#xff0c;能够表示为奇数多个对换乘积的置换称为“奇置换”&#xff0c;能够表示为偶数多个对换乘积的置换称为“偶置换”&#xff1b; ②所有偶置换的集合记为An。 例1&#xff1a;&#xff08;1&#xff09;计算S1和S2中奇、偶置换的数目&…

数据中台-知识图谱平台

【数据分析小兵】专注数据中台产品领域,覆盖开发套件,包含数据集成、数据建模、数据开发、数据服务、数据可视化、数据治理相关产品以及相关行业的技术方案的分享。对数据中台产品想要体验、做二次开发、关注方案资料、做技术交流的朋友们&#xff0c;可以关注我。 1. 概述 随着…

ResNet——Deep Residual Learning for Image Recognition(论文阅读)

1.什么是ResNet ResNet是一种残差网络&#xff0c;咱们可以把它理解为一个子网络&#xff0c;这个子网络经过堆叠可以构成一个很深的网络。下面是ResNet的结构。 2.为什么要引入ResNet 理论上来说&#xff0c;堆叠神经网络的层数应该可以提升模型的精度。但是现实中真的是这…

智慧守护 畅游无忧——北斗应急呼叫柱,为景区安全加码

在大自然的怀抱中&#xff0c;中型及大型公园、景区以其壮丽风光吸引着成千上万的游客前来探索&#xff0c;成为了人们休闲娱乐的好去处。然而&#xff0c;广袤的区域、复杂的地形和分散的人流也给安全保障带来了前所未有的挑战。传统的巡逻方式难以覆盖每一个角落&#xff0c;…

【第六篇】SpringSecurity的权限管理

一、权限管理的实现 服务端的各种资源要被SpringSecurity的权限管理控制可以通过注解和标签两种方式来处理。 放开了相关的注解后在Controller中就可以使用相关的注解来控制了 JSR250注解 /*** JSR250*/ @Controller @RequestMapping("/user") public class UserC…

物理隔离后数据怎么导入和导出?安全U盘一键解决

政府单位、军工和科研所、航空航天企业、金融机构、医疗单位、电力企业、生物制药实验室等企业及单位&#xff0c;因研发和生产过程、或日常经营中涉及大量敏感信息和技术&#xff0c;需要通过物理隔离来确保网络的安全性。因此&#xff0c;多采用物理隔离的方式进行网络建设。…

前端 CSS 经典:在 Vue3 中使用渐进式图片

1. 什么是渐进式图片 当我们网站会加载很多图片的时候&#xff0c;有些图片尺寸很大&#xff0c;加载就会很慢&#xff0c;会导致页面长时间陷入白屏状态&#xff0c;用户体验很不好。所以可以使用渐进式图片&#xff0c;先给用户展示模糊图&#xff0c;这些图尺寸小&#xff…

django学习入门系列之第二点《浏览器能识别的标签3》

文章目录 列表表格往期回顾 列表 无序列表 <!-- <ul </ul> 无序列表 --> <ul><li> 内容1 </li><li> 内容2 </li><li> 内容3 </li><li> 内容4 </li> </ul>有序列表 <!-- <ol> &…

WordPress、Typecho 站点如何让 CloudFlare 缓存加速

众所周知 WordPress、Typecho 都是著名动态博客站点(一个最简单的判断依据就是都要依赖结合数据库),这类站点在 CDN 缓存上都有一个致命的缓存弊端就是动静态请求的区分,理论上要让 CDN 绕过所有的动态请求,缓存所有的静态请求,否则就会造成前端登录和非登录状态的混乱,…