数据结构Java版(4)——链表

一、概述

        链表是一种常见的数据结构,用于存储一系列具有相同类型的数据元素。它由多个节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。

        链表与数组不同,它的节点在内存中不是连续存储的,而是通过每个节点中的指针链接在一起。这使得链表的插入和删除操作更加高效,但访问任意节点时需要遍历链表,因此访问操作的效率较低。

        链表通常具有一个头节点,用于指向链表的第一个节点。如果链表为空,则头节点为空。在链表末尾,最后一个节点的指针通常为NULL,表示链表的结束。

         链表有多种类型,包括单链表、双向链表和循环链表。单链表只有一个指向下一个节点的指针,双向链表有两个指针,一个指向前一个节点,一个指向后一个节点,而循环链表的最后一个节点的指针指向链表的头节点。

        链表的优点是插入和删除操作的高效性,特别是在链表的中间位置。链表的缺点是访问操作的效率较低,因为需要遍历链表。另外,由于链表的节点需要存储额外的指针,所以链表比数组占用更多的内存空间。

        总之,链表是一种灵活且常用的数据结构,在许多应用中都有广泛的应用。

        在Java中,因为取消了指针,所以我们只能用内部类的方式来处理节点和节点之间的关联关系。

二、链表的特点

        链表是真正的动态数据结构,不同于数组的扩容和缩容,链表本身通过next来连接下一个节点,不会存在内存浪费和溢出的情况,同时,链表也是最简单的数据结构,掌握链表可以帮助我们学习更复杂的数据结构,如图和树。学习链表也有助于更深入的理解引用和递归。

        在Java中,本身也给我们提供了一种链表LinkedList,它是一个泛型类,实现了栈和队列等一系列接口方法,在学习算法和开发中会经常用到,十分的灵活好用。

三、链表的实现

        为了更深刻的理解链表这种数据结构,我们将自己编写一个链表,代码如下,供读者参考:

代码实现

public class LinkedList<T> {//节点class Node<T>{//数据域T data;//指针域Node<T> next;public Node(T data) {this.data = data;}public Node(T data, Node<T> next) {this.data = data;this.next = next;}}//链表的头节点private Node<T> Head;//链表的长度private int length;//初始化public LinkedList(){//创建头节点,下一个为首元节点this.Head = new Node<T>(null,null);this.length = 0;}//判断链表是否为空public boolean isEmpty(){return getLength()==0;}//获得链表长度public int getLength(){return this.length;}//添加节点//头插法public boolean addFirst(T data){return add(data,1);}//在第几个位置插入元素public boolean add(T data,int index){if(index > getLength()+1 || index < 1) return false;index--;Node<T> tempNode = this.Head;int index_ = 0;while (tempNode!=null&&index!=index_){tempNode = tempNode.next;index_++;}tempNode.next = new Node(data,tempNode.next);this.length++;return true;}//尾插法public boolean addLast(T data){return add(data,getLength()+1);}//遍历,这里借用Object.toString的方法,将其进行重写@Overridepublic String toString() {Node<T> tempNode = this.Head.next;StringBuilder builder = new StringBuilder();while (tempNode!=null){builder.append(tempNode.data + "->");tempNode = tempNode.next;}builder.append("NULL");return builder.toString();}//查找元素是否存在public boolean isHave(T data){Node<T> tNode = this.Head.next;while (tNode!=null){if(tNode.data.equals(data)) return true;tNode = tNode.next;}return false;}//获取指定位置元素//获取首元节点元素public T getFirst(){return get(1);}//获取指定位置元素public T get(int index){if(index > getLength() || index < 1) return null;index--;Node<T> tempNode = this.Head;int index_ = 0;while (tempNode!=null&&index!=index_){tempNode = tempNode.next;index_++;}return tempNode.next.data;}//获取尾节点元素public T getLast(){return get(getLength());}//删除节点//删除头节点public T removeFirst(){return remove(1);}//删除指定位置节点public T remove(int index){if(index > getLength() || index < 1) return null;index--;Node<T> tempNode = this.Head;int index_ = 0;while (tempNode!=null&&index!=index_){tempNode = tempNode.next;index_++;}T res = tempNode.next.data;tempNode.next = tempNode.next.next;this.length--;return res;}//删除尾节点public T removeLast(){return remove(getLength());}//删除第一个指定元素的节点public boolean remove(T data){Node<T> tempNode = this.Head;while (tempNode.next!=null){if(tempNode.next.data.equals(data)){tempNode.next = tempNode.next.next;this.length--;return true;}tempNode = tempNode.next;}return false;}//删除链表中所有是这个元素的节点public int removeAll(T data){int count = 0;while (remove(data)) count++;return count;}//修改指定位置的值public boolean set(T data,int index){remove(index);return add(data,index);}//使用递归的方式删除链表元素public void remove_all_by_recursion(T value){this.Head.next = recursion_remove(value,this.Head.next);}private Node recursion_remove(T value,Node node){//递归终止条件if(node==null) return null;//递归操作if(node.data.equals(value)){this.length--;return node.next;}else {node.next = recursion_remove(value,node.next);return node;}}
}

测试链表

import java.util.Random;public class testMyLinked {public static void main(String[] args) {Random random = new Random();LinkedList<Integer> linkedList = new LinkedList<>();System.out.println(linkedList.getFirst());System.out.println(linkedList.getLast());for(int i = 0;i < 10;i++){linkedList.addLast(random.nextInt(10));System.out.println(linkedList.toString());}linkedList.add(666,5);for(int i = 0;i < 10;i++){linkedList.addFirst(random.nextInt(10));System.out.println(linkedList.toString());}System.out.println(linkedList.isHave(666));System.out.println(linkedList.add(1145, 10));System.out.println(linkedList.isHave(114));System.out.println(linkedList.get(15));System.out.println(linkedList.getFirst());System.out.println(linkedList.getLast());System.out.println(linkedList.remove(16));System.out.println(linkedList.toString());System.out.println(linkedList.removeFirst());System.out.println(linkedList.removeLast());System.out.println(linkedList.toString());System.out.println(linkedList.remove(new Integer(1145)));System.out.println(linkedList.toString());System.out.println(linkedList.removeAll(new Integer(6)));System.out.println(linkedList.toString());System.out.println(linkedList.set(1919, 6));System.out.println(linkedList.toString());linkedList.remove_all_by_recursion(4);System.out.println(linkedList.toString());}
}

输出结果:

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

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

相关文章

测试C#调用OpenCvSharp和ViewFaceCore从摄像头中识别人脸

学习了基于OpenCvSharp获取摄像头数据&#xff0c;同时学习了基于ViewFaceCore的人脸识别用法&#xff0c;将这两者结合即是从摄像头中识别人脸。本文测试测试C#调用OpenCvSharp和ViewFaceCore从摄像头中识别人脸&#xff0c;并进行人脸红框标记。   新建Winform项目&#xf…

OpenSource - 文件在线预览模块(多格式转 PDF 文件)

文章目录 文件在线预览模块&#xff08;多格式转PDF文件&#xff09;现已支持格式如下界面展示运行方式接口介绍文件上传文件转 PDF文件转图片文件转SVG 参数配置其他说明项目关联关键词文档转换预览技术说明同步转换异步转换 主要技术乱码问题处理帮助文档 前端预览弹出层用法…

整除的特征及解释

整除的特征及解释 整除的含义 简单地说&#xff0c;当一个非零整数除另一个整数得到整数商而没有余数时&#xff0c;叫做整除。如62&#xff1d;3&#xff0c;就说2整除6或6能被2整除。 用数学语言描述&#xff1a;若整数b除以非零整数a&#xff0c;商为整数&#xff0c;且余…

zookeeper弱密码漏洞修复

1.连接zookeeper 进入zookeeper安装目录 bin目录下 ./zkCli.sh -server IP:21812.查看节点 ls /3.查看节点权限 getAcl /zookeeper4.设置IP权限 setAcl / ip:127.0.0.1:cdrwa,ip:10.86.30.11:cdrwazookeeper的权限不具备继承性,父子节点的权限相互独立,因此需要为每个子…

11- OpenCV:自定义线性滤波(卷积,卷积边缘)

目录 一、卷积 1、卷积概念 2、卷积如何工作 3、常见算子&#xff08;卷积核 Kenel&#xff09; 4、自定义卷积模糊 5、代码演示 二、卷积边缘 1、卷积边缘问题 2、处理边缘 3、相关的API说明 4、代码演示 一、卷积 1、卷积概念 &#xff08;1&#xff09;在OpenC…

生成当天递增唯一的流水号的几种方式

说明&#xff1a;当开发中&#xff0c;如交易、文件传输过程中的文件名&#xff0c;可能需要我们使用一串唯一的数字来锁定这一条“交互记录”&#xff0c;即流水号。 本文介绍几种生成6位递增唯一&#xff0c;且每日重置的流水号的方式。 方式一&#xff1a;使用Redis 我们…

SpringSecurity(11)——核心组件和认证流程

获取用户信息 // 获取安全上下文对象&#xff0c;就是那个保存在 ThreadLocal 里面的安全上下文对象 // 总是不为null(如果不存在&#xff0c;则创建一个authentication属性为null的empty安全上下文对象) SecurityContext securityContext SecurityContextHolder.getContext(…

微信轰炸-python实现方法

新手&#xff0c;一般都需要执行以下命令&#xff0c;用来导入对应模块 pip install -i Simple Index pynput 键盘winr进入输入cmd 执行该命令即可&#xff1a;pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pynput 打开pycharm,输入代码如下 from pynput.keybo…

AI视频智能识别技术在智慧农业大棚升级改造管理场景中的应用方案

一、需求分析 随着科技的进步和农业现代化的推进&#xff0c;智能化技术逐渐成为现代农业发展的重要支撑。农业大棚作为现代农业的重要组成部分&#xff0c;其智能化改造对于提高农业生产效率、降低成本、增加收益具有重要意义。利用先进的信息化手段来对农业大棚进行管理&…

NOC总线(2)

1. NoC的路由 在NoC交换信息时&#xff0c;需要确定从源节点到目标节点所经过的路径&#xff0c;这时就需要路由算法来确定该路径。路由算法分为静态路由算法和动态路由算法两种。 静态路由算法对于两节点之间的路径是固定的&#xff0c;结构简单&#xff0c;便于硬件实…

【算法分析与设计】二叉树的层序遍历

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 题目 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xf…

idea插件开发

1&#xff0c; file-new project 如图&#xff0c;选择了安装路径&#xff0c;报错【select home directory for intellij platform plugin sdk】。&#xff08;注意是安装路径最外层的文件夹&#xff0c;不是里面的lib&#xff0c;jbr这一层级&#xff09; 2&#xff0c;点击了…

HTML前端CSS实现只显示1行或者2行、3行剩余显示省略号

想要做的效果: 文本只一行显示 /**实现思路&#xff1a;1.设置inline-block属相2.强制不换行3.固定高度4.隐藏超出部分5.显示“……”*/ {display: inline-block;white-space: nowrap; width: 100%; overflow: hidden;text-overflow:ellipsis; }文本只多行显示 /** 实现思路&…

【Java发送邮箱】spring boot 发送邮箱

导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId> </dependency> 2.在properties配置邮箱 # 发件人QQ号 spring.mail.username2508575653qq.com # QQ邮箱授权码 sp…

xshell配置隧道转移规则

钢铁知识库&#xff0c;一个学习python爬虫、数据分析的知识库。人生苦短&#xff0c;快用python。 xshell是什么 通俗点说就是一款强大ssh远程软件&#xff0c;可以方便运维人员对服务器进行管理操作&#xff0c;功能很多朋友们自行探索&#xff0c;今天只聊其中一个功能点那…

HNU-数据挖掘-实验2-数据降维与可视化

数据挖掘课程实验实验2 数据降维与可视化 计科210X 甘晴void 202108010XXX 文章目录 数据挖掘课程实验<br>实验2 数据降维与可视化实验背景实验目标实验数据集说明实验参考步骤实验过程1.对数据进行初步降维2.使用无监督数据降维方法&#xff0c;比如PCA&#xff0c;I…

既是API调试平台也是自动化测试工具?Apipost

Apipost提供可视化的API自动化测试功能&#xff0c;使用Apipost研发人员可以设计、调试接口&#xff0c;测试人员可以基于同一数据源进行测试&#xff0c;Apipost 接口自动化功能在上次更新中进行了逻辑调整&#xff0c;带来更好的交互操作、更多的控制器选择&#xff0c;同时新…

SpringMvc中拦截器的配置及应用

拦截器原理 在 Spring MVC 中&#xff0c;拦截器&#xff08;Interceptor&#xff09;是一种机制&#xff0c;用于拦截请求并在处理程序&#xff08;Controller&#xff09;执行之前或之后执行一些操作。拦截器允许您在请求的不同阶段&#xff08;如处理程序执行前、处理程序执…

AI大模型中的Bert

1.全方位上下文理解&#xff1a;与以前的模型&#xff08;例如GPT&#xff09;相比&#xff0c;BERT能够双向理解上下文&#xff0c;即同时考虑一个词 的左边和右边的上下文。这种全方位的上下文理解使得BERT能够更好地理解语言&#xff0c;特别是在理解词义、 消歧等复杂任务上…

智慧安防GB28181视频监控EasyCVR v3.5系统增加录像保存地址的配置

智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入。在网络传输上&#xff0c;平台支持设备通过4G、5G、WIFI、有线等方式进行视频流的快捷传输&#xff0c;视频流经平台处理后可对外进行多格式的分发&#xff0c;实现多展示终端观看&am…