【2】单链表

【2】单链表

  • 1、单链表
  • 2、单链表的设计
  • 3、接口设计
  • 4、SingleLinkedList
  • 5、node(int index) 返回索引位置的节点
  • 6、clear()
  • 7、添加
  • 8、删除
  • 9、indexOf(E element)

1、单链表

📕动态数组有个明显的缺点
🖊 可能会造成内存空间的大量浪费
📕 能否用到多少就申请多少内存?
🖊 链表可以办到这一点

📕 链表是一种链式存储的线性表,所有元素的内存地址不一定连续
在这里插入图片描述

🖊 每个节点中有一个成员变量指记录着下一个节点的内存地址

2、单链表的设计

在这里插入图片描述

🍀 size 存储单链表的节点个数
🍀 first 被称作头指针:指向头节点
🍀 每个节点(Node)中有 element 属性存储具体的数据;next 属性存储下一个节点的内存地址
🍀 尾节点的 next 属性为 null
🍀 单链表也是线性表(有索引的概念)

3、接口设计

📕 链表的大部分接口和动态数组是一致的
在这里插入图片描述

在这里插入图片描述

public interface List<E> {/*** 返回存储的元素数量*/int size();/*** 是否为空*/boolean isEmpty();/*** 是否包含给定元素*/boolean contains(E element);/*** 返回索引位置的元素*/E get(int index);/*** 返回指定元素的索引*/int indexOf(E element);/*** 添加元素到尾部*/void add(E element);/*** 往索引位置添加元素*/void add(int index, E element);/*** 删除索引位置的元素** @return 被删除的元素*/E remove(int index);/*** 清空所有元素*/void clear();/*** 设置索引位置的元素*/E set(int index, E element);
}

4、SingleLinkedList

在这里插入图片描述

📕往单链表中添加一个数据就会创建的一个 Node 对象

public class SingleLinkedList<E> implements List<E> {private int size;private Node<E> first;/*** 返回存储的元素数量*/@Overridepublic int size() {return 0;}/*** 是否为空*/@Overridepublic boolean isEmpty() {return false;}/*** 是否包含给定元素*/@Overridepublic boolean contains(E element) {return false;}/*** 返回索引位置的元素*/@Overridepublic E get(int index) {return null;}/*** 返回指定元素的索引*/@Overridepublic int indexOf(E element) {return 0;}/*** 添加元素到尾部*/@Overridepublic void add(E element) {}/*** 往索引位置添加元素*/@Overridepublic void add(int index, E element) {}/*** 删除索引位置的元素** @return 被删除的元素*/@Overridepublic E remove(int index) {return null;}/*** 清空所有元素*/@Overridepublic void clear() {}/*** 设置索引位置的元素*/@Overridepublic E set(int index, E element) {return null;}private static final class Node<E> {private E element;private Node<E> next;public Node(E element, Node<E> next) {this.element = element;this.next = next;}}}

5、node(int index) 返回索引位置的节点

在这里插入图片描述

🖊 若需要 index 位置的节点,则从 first 头指针指向的头节点开始 next index 次即可

	/*** 返回index索引处的节点*/private Node<E> node(int index) {checkIndex(index);Node<E> node = first;for (int i = 0; i < index; i++) {node = node.next;}return node;}

📕 get(int index) 方法

    /*** 返回索引位置的元素*/@Overridepublic E get(int index) {return node(index).element;}

📕 set(int index, E element) 方法

    /*** 设置索引位置的元素*/@Overridepublic E set(int index, E element) {Node<E> node = node(index);E e = node.element;node.element = element;return e;}

6、clear()

在这里插入图片描述

🖊 first 头指针指向 null,则头节点会被Java的垃圾回收器回收
🖊 头节点的内存被回收会导致它 next 指向的节点也被回收,最终整个链表就被清空了

    /*** 清空所有元素*/@Overridepublic void clear() {first = null;size = 0;}

7、添加

在这里插入图片描述

🖊 如果 index == 0(把元素添加到头节点位置):直接让 first 头指针指向新节点,新节点的 next 指向之前的头节点
🖊 如果 index != 0:① 找到 index - 1 索引处的节点 prev;② 新节点的 next 指向 prev.next;③ prev.next 指向新节点

   * 往索引位置添加元素*/@Overridepublic void add(int index, E element) {checkIndex4Add(index);if (index == 0) {first = new Node<>(element, first);} else {Node<E> prev = node(index - 1);prev.next = new Node<>(element, prev.next);}size++;}

📕 在编写链表代码时,要注意边界测试,比如 index 为 0size – 1size

边界介绍
0往头节点位置添加元素
size-1边界检查通过
size往链表尾部添加元素
    /*** 添加元素到尾部*/@Overridepublic void add(E element) {add(size, element);}

8、删除

在这里插入图片描述

🖊 如果 index == 0(删除头节点元素):直接用头指针 first 指向 first.next
🖊 如果 index != 0:① 找到前一个节点 prev;② prev.next 指向 prev.next.next

    /*** 删除索引位置的元素** @return 被删除的元素*/@Overridepublic E remove(int index) {checkIndex(index);Node<E> node = first;if (index == 0) {first = first.next;} else {Node<E> prev = node(index - 1);node = prev.next;prev.next = node.next;}size--;return node.element;}

📕 在编写链表代码时,要注意边界测试,比如 index 为 0size – 1size

边界介绍
0删除头节点
size-1边界检查通过
size抛异常

9、indexOf(E element)

📕 从 first 开始挨个遍历比较
🖊 考虑 element == null 的情况

    /*** 返回指定元素的索引*/@Overridepublic int indexOf(E element) {Node<E> node = first;if (element == null) {for (int i = 0; i < size; i++) {if (node.element == null) return i;node = node.next;}} else {for (int i = 0; i < size; i++) {if (element.equals(node.element)) return i;node = node.next;}}return ELEMENT_NOT_FOUND;}

🍀😀 单链表完整代码

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

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

相关文章

基于pear-admin-flask 的 flask 使用教程

我最近接触到了一个极为出色的Flask后台库——pear-admin-flask&#xff0c;这个库具有很高的二次开发价值。借此机会学习并吸收其中Flask开发的一些高级技巧。 1. flask 自定义命令 pear-admin-flask/applications/common/script/admin.py from flask.cli import AppGroup …

CUDA从入门到放弃(十四):CUDA Thrust库

CUDA从入门到放弃&#xff08;十四&#xff09;&#xff1a;CUDA Thrust库 Thrust 是一个基于标准模板库&#xff08;STL&#xff09;的 C 模板库&#xff0c;专为 CUDA 设计&#xff0c;旨在简化高性能并行应用的开发。它提供了一系列数据并行原语&#xff0c;如扫描、排序和…

vue基础教程(4)——十分钟吃透vue路由router

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、路由概念二、路由使用三、创建路由对应的组件四、给整个项目一个入口总结 前言 前面的文章运行成功后&#xff0c;页面显示如下&#xff1a; 在这个页面中&#xff0c;点击Home和About都会切换右面的页面内容&#…

《责任链模式(极简c++)》

本文章属于专栏- 概述 - 《设计模式&#xff08;极简c版&#xff09;》-CSDN博客 模式说明 方案&#xff1a; 责任链模式将请求的发送者和接收者解耦&#xff0c;构成一个链条&#xff0c;并由多个对象对请求进行处理&#xff0c;直到找到合适的处理者为止。优点&#xff1a; …

iOS UIFont-真香警告之字体管理类

UIFont 系列传送门 第一弹加载本地字体:iOS UIFont-新增第三方字体 第二弹加载线上字体:iOS UIFont-实现三方字体的下载和使用 第三弹搭建字体管理类:iOS UIFont-真香警告之字体管理类 前言 不知道友们是否有过这种经历,项目已经迭代了很多版本,项目中的文件已经上千个了…

uniapp数组合并函数使用几录

let that { listAll: [1, 2, 3] }; let data [4, 5, 6]; let mergedArray that.listAll.concat(data); console.log(mergedArray); // 输出: [1, 2, 3, 4, 5, 6] console.log(that.listAll); // 输出: [1, 2, 3]&#xff0c;原始数组没有改变 唯有美景&#xff0c;可以抚…

基于SSM+Jsp+Mysql的医院远程诊断系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

故障诊断 | 基于FTNN网络模型的故障诊断(Pytorch)

效果分析 基本介绍 FTNN是一种基于神经网络的故障诊断模型,它旨在识别和定位系统中的故障。使用已标记的数据集对FTNN模型进行训练。标记的数据集包括系统在正常和故障状态下的数据,以及对应的故障标签。通过算法和优化方法,调整网络参数以最小化预测误差。使用独立的测试数…

linux三剑客之grep

grep命令 基本语法 示例 搜索文件 example.txt 中包含单词 "example" 的所有行: grep -v "example" example.txt 计算文件 example.txt 中包含 "example" 的行数: grep -c "example" example.txt 显示 example.txt 中包含 "e…

SQLite中的隔离(八)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite版本3中的文件锁定和并发(七&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 数据库的“isolation”属性确定何时对 一个操作的数据库对其他并发操作可见。 数据库连接之间的隔离 如果使用两个不…

Flume面试题及参考答案

在大数据领域,Flume是一个不可或缺的工具,它负责可靠地收集、聚合和移动大量日志数据。作为一名大数据架构师,掌握Flume的工作原理和最佳实践对于构建高效的数据处理流水线至关重要。本文将深入探讨一系列Flume面试题,并提供详尽的参考答案,以帮助读者在面试中表现出色,并…

LeetCode-2908. 元素和最小的山形三元组 I【数组,前后缀分解】

LeetCode-2908. 元素和最小的山形三元组 I【数组】 题目描述&#xff1a;解题思路一&#xff1a;暴力解法&#xff0c;三个for循环解题思路二&#xff1a;优化&#xff0c;这里注意到1 < nums[i] < 50&#xff0c;其实如果有山形三元组&#xff0c;那么result是一定小于等…

汽车电子行业知识:汽车电子领域包含哪些技术

汽车电子行业涉及到许多方面的知识&#xff0c;包括但不限于&#xff1a; 汽车电子控制单元&#xff08;ECU&#xff09;&#xff1a;负责监控和控制车辆的各种系统&#xff0c;如发动机控制单元、制动系统控制单元、空调系统控制单元等。汽车传感器技术&#xff1a;包括温度传…

Luigi任务调度框架学习2:运行每一个Task,避免因判定完成导致跳过执行Task主程序

在上一篇Luigi的线性调度文章中&#xff08;Luigi任务调度框架学习1&#xff1a;线性调用流程&#xff09;&#xff0c;我们知道Task运行的时候&#xff1a; 每个任务是否完成有两次判定&#xff0c;即&#xff1a;进行判定(未完成) 》运行def run(self)函数 》进行判定(完成) …

国产暴雨AI服务器X3418开启多元自主可控新篇章

在当前数字化转型的大潮中&#xff0c;算力作为新质生产力的重要动力引擎&#xff0c;对推动经济社会发展起着关键作用。尤其在人工智能领域&#xff0c;随着高性能、安全可控的AI算力需求持续攀升&#xff0c;国产化服务器的研发与应用显得尤为迫切。 作为国内专业的算力基础…

mysql5.7 源码分析--初始化

集中在sql\mysqld.cc文件的mysqld_main函数中&#xff08;&#xff09;&#xff1a; 主程序入口 在sql\main.cc文件中&#xff1a; int main(int argc, char **argv) {return mysqld_main(arg, argv); } 一、mysql为了跨平台&#xff0c;对win32系统做了单独的初始化&#x…

【ENSP】交换机和路由器之间实现静态路由

1.概念 三层交换机只能在Vlanif逻辑口配置iP地址 路由器的每一个端口都是另外一个网段 2.实现方法 交换机允许对应vlan通行&#xff0c;配置vlanif的ip地址&#xff0c;做静态路由 路由器&#xff0c;进接口配置对应的ip&#xff0c;路由器和交换机相连的口&#xff0c;进入他的…

文心一言 VS 讯飞星火 VS chatgpt (225)-- 算法导论16.3 7题

七、推广赫夫曼算法&#xff0c;使之能生成三进制的码字(即码字由符号0、1、2组成)&#xff0c;并证明你的算法能生成最优三进制码。如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 推广赫夫曼算法以生成三进制码字需要对算法进行一定的修改&#xff0c;确保在每…

JavaScript是如何实现页面渲染的

JavaScript实现页面渲染主要涉及到对DOM的操作、样式的修改以及与后端数据的交互。以下是JavaScript实现页面渲染的主要步骤和方式&#xff1a; 一、DOM操作 创建和修改元素&#xff1a;JavaScript可以使用document.createElement()来创建新的DOM元素&#xff0c;使用appendC…

力软框架打开新的对话框,点击对话框确认按钮的事件AcceptClick的方法

// 原来在力软框架下&#xff0c;点击哪个确认按钮的时候 top.frames[iframeId].AcceptClick直接用这个方法就可以了 &#xff0c;那个方法是直接返回方法的但是不知道是什么情况。如图二所示。死活就返回了ifram标签不知道是什么原因&#xff0c;就获取不到对话框里边自己定义…