【算法】Java-使用数组模拟单向链表,双向链表
目录
试题1:实现一个单链表,并实现以下功能:
试题2:实现一个双链表,并实现以下功能
思路总结:
什么情况下可能涉及到用数组实现链表呢?
在学习时了解到了可以用数组模拟链表,使其兼顾数据查找快,链表新增和删除快的缺点,找来一些试题实现了下,如下:
试题1:实现一个单链表,并实现以下功能:

Java代码实现:
import org.apache.commons.lang3.StringUtils;import java.util.Scanner;public class ArrayLinkedList {public static final int N = 100000;private int head; // headprivate int idx; // 存储新元素的索引下标private int[] e; // 存放数据的数组;private int[] ne; // 当前节点的下一个节点的地址(数组下标)。比如使用头插法,单向链表,e[5] = 5,e[5]的下一个节点的坐标是ne[5],下一个节点是e[ne[5]]public ArrayLinkedList() {e = new int[N];ne = new int[N];head = -1;idx = 0;}public void insertToHead(int val) {e[idx] = val;ne[idx] = head; // head的值是头结点指向的下一个元素的下标值head = idx++;}/*** 将val插入到索引k后面** @param k* @param val*/public void insert(int k, int val) {e[idx] = val;ne[idx] = ne[k];ne[k] = idx++;}/*** 删除k节点后面的节点(只删一个)** @param k*/public void remove(int k) {if (k + 1 == 0) {head = ne[head];} else {ne[k] = ne[ne[k]];}}public static void main(String[] args) {System.out.println("请输入:");Scanner scanner = new Scanner(System.in);ArrayLinkedList arrayLinkedList = new ArrayLinkedList();int head = arrayLinkedList.head;int[] e = arrayLinkedList.e;int[] ne = arrayLinkedList.ne;while (scanner.hasNextLine()) {String inputString = scanner.nextLine();if (StringUtils.isBlank(inputString)) {break;}String[] inputArr = inputString.split(" ");String f = inputArr[0];int s = Integer.valueOf(inputArr[1]);switch (f) {case "H":arrayLinkedList.insertToHead(s);break;case "D":arrayLinkedList.remove(s - 1); // 第k个插入的数,idx是k-1break;case "I":int val = Integer.valueOf(inputArr[2]);arrayLinkedList.insert(s - 1, val);break;}}for (int i = head; i != -1; i = ne[i]) {System.out.print(e[i] + " ");}scanner.close();}
}
试题2:实现一个双链表,并实现以下功能
Java代码实现:
import org.apache.commons.lang3.StringUtils;import java.util.Scanner;/*** 支持的操作:* 1、在最左侧插入一个数;* 2、在最右侧插入一个数;* 3、将第k个插入的数删除;* 4、在第k个插入的数左侧插入一个数;* 5、在第k个插入的数右侧插入一个数*/
public class TwoWayLinkedList2 {public static final int N = 100000;// 存放数组的数据private int[] e;// 存放左指针下标数组private int[] l;// 存放右指针地址数组private int[] r;// 数组待存储下标private int idx;// e[0]表示链表头;e[1]表示链表尾// 向左侧插入,就是插入到上一个节点的右侧。所以插入的逻辑都抽象成插入到具体节点的右侧// 构造方法public TwoWayLinkedList2() {e = new int[N];r = new int[N];l = new int[N];r[0] = 1;l[1] = 0;idx = 2;}/*** 将节点插入到e[k]节点右侧** @param k* @param val*/public void add(int k, int val) {e[idx] = val;l[idx] = k;r[idx] = r[k];l[r[k]] = idx;r[k] = idx;idx++;}/*** 删除e[k]** @param k*/public void remove(int k) {r[l[k]] = r[k];l[r[k]] = l[k];}public static void main(String[] args) {System.out.println("请输入:");Scanner scanner = new Scanner(System.in);TwoWayLinkedList2 linkedList = new TwoWayLinkedList2();int[] e = linkedList.e;int[] l = linkedList.l;int[] r = linkedList.r;while (scanner.hasNextLine()) {String inputString = scanner.nextLine();if (StringUtils.isBlank(inputString)) {break;}String[] inputArr = inputString.split(" ");String f = inputArr[0];Integer s = Integer.valueOf(inputArr[1]);switch (f) {case "L":linkedList.add(0, s);break;case "R":linkedList.add(l[1], s);break;case "D":linkedList.remove(s + 1); // 第k个插入的数,idx是k+1,因为我们用了0和1表示链表头和链表尾break;case "IL":linkedList.add(l[s + 1], Integer.valueOf(inputArr[2]));break;case "IR":linkedList.add(s + 1, Integer.valueOf(inputArr[2]));break;}}// 遍历输出for (int i = r[0]; i != 1; i = r[i]) {System.out.printf("" + e[i]);}scanner.close();}
}
思路总结:
数组实现链表,一个数组用于存放数据,一个数组存放"指针",这里的指针用数组下标代替。如果是双向链表,要用两个数组存放指针。同时要注意首节点和尾结点的记录方法。在实现双链表时,我曾用两个变量表示首尾节点,对比起来,没有用e[0],e[1]表示简洁,而且非常容易搞混。占用第0位和第1位保存链表头和尾时要注意初始的idx=2,第k个插入的元素的索引下标是k+1。大家可以使用更多方法实现,过程虽然曲折,但一顿操作下来,对链表的操作会非常的熟练。
什么情况下可能涉及到用数组实现链表呢?
在没有操作系统和内存管理的情况下。
1. 链表的实现需要动态内存分配和释放,这需要操作系统提供的堆内存管理。没有 OS 的动态内存管理,就无法真正实现链表节点的创建和销毁。
2. 链表通过指针链接节点,需要操作系统提供的指针和地址引用机制。没有 OS,就无法真正用指针建立节点之间的链接关系。
3. 数组可以预先分配一块内存,这个内存块可以视为堆内存,用下标代替指针,通过数组操作就可以模拟出指针操作。
4. 数组是一块连续的内存,空间固定,不需要动态扩展,所以定义数组后直接就可以使用,不依赖动态内存管理。
5. 数组中的每个元素是连续存储的,通过下标可以直接访问,不需要指针来进行寻址。可以模拟指针的移动,改变指针的指向来实现链表的操作。
这里我们从算法分析和学习的角度来看这个问题,但不适合实际项目,只能处理规模较小的数据。要实现一个真正的可扩展链表,还需在操作系统上进行动态内存管理。
相关文章:
【算法】Java-使用数组模拟单向链表,双向链表
目录 试题1:实现一个单链表,并实现以下功能: 试题2:实现一个双链表,并实现以下功能 思路总结: 什么情况下可能涉及到用数组实现链表呢? 在学习时了解到了可以用数组模拟链表,使其…...
Nessus简单介绍与安装
Nessus简单介绍与安装 1.Nessus简介 Nessus号称是世界上最流行的漏洞扫描程序,全世界有超过75000个组织在使用它。该工具提供完整的电脑漏洞扫描服务,并随时更新其漏洞数据库。Nessus不同于传统的漏洞扫描软件,Nessus可同时在本机或远端上遥…...
【每天一道算法题】day2-认识时间复杂度
认识时间复杂度: O:读作big O,在数学上指的是上限的意思 常数时间的操作 一个操作如果和样本的数据量没有关系,每次都是固定时间内完成的操作,叫做常数操作。时间复杂度为一个算法流程中,常数操作数量的一…...
前端报错合集
error Component name “index“ should always be multi-word vue/multi-word-component-names 的解决办法 原因组件命名是 没有采用驼峰 error Component name “index“ should always be multi-word vue/multi-word-component-names 的解决办法_error component name &qu…...
Milvus以及Web UI 安装
向量数据库懂的都懂 版本数据 [rootiZ7xv7q4im4c48qen2do2bZ project]# cat /etc/redhat-release CentOS Stream release 9 [rootiZ7xv7q4im4c48qen2do2bZ project]# docker version Client: Docker Engine - CommunityVersion: 24.0.5API version: 1.43Go v…...
Go for循环中的defer
背景 写个后台程序,定时抓取服务器指标,代码逻辑如下,使用一段时间后内存不断增加 func CollectInfo() {for {// 获取服务器信息代码// ...............resp, err : http.Post("http://server", "application/json", str…...
创建开机自启的脚本
在启动许多ros节点时有多种方式,我推荐使用launch来启动所有的节点,这也是一种规范的方式。以后会慢慢向这个方向靠。 除此之外还可以通过创建的脚本来启动: 脚本位置不限,只需要: sudo gedit xxx.sh在里面添加相应的…...
学生信息系统(python实现)
#codingutf-8 import os.path filenamestudent.txtdef menm():#菜单界面print(学生管理系统)print(-----------------------------功能菜单-----------------------------)print(\t\t\t\t\t\t1.录入学生信息)print(\t\t\t\t\t\t2.查找学生信息)print(\t\t\t\t\t\t3.删除学生信息…...
管理类联考——数学——汇总篇——知识点突破——数据分析——1. 计数原理——排列组合——公式
排列组合 排列与组合的推导: 从n个不同的元素中取出m(m≤n)个元素做排列为 A n m A_n^m An...
C#,《小白学程序》第十六课:随机数(Random)第三,正态分布的随机数的计算方法与代码
1 随机数的问题 用 C# Random 类生成的随机数是平均分布的。也就是各数据段的出现的次数差不多。彩票号码属于这种随机数。 而很多很多常见的随机数,比如:成绩,却是符合正态分布的。 因而很多时候需要生成符合正态分布规律的随机数。 2 文…...
一文读懂java变量类型
前言 在学习和使用Java编程语言时,理解变量类型是至关重要的基础知识。Java是一种静态类型语言,强调变量必须先声明其类型,才能进行后续操作。因此,对于初学者来说,了解Java中不同的变量类型及其特性是迈向编程成功的…...
解决windows下git操作提示用户名密码错误的问题
当代码从一个平台切换到另一个平台的时候,需要做两步操作,第一步就是更新git的仓库地址,在项目的.git/config文件里面修改,这一步做完之后,就可以推送代码到新的仓库了,这里就是重点来了。 一般第一次推动代…...
ESP32开发:Clion配置IDF
IDF环境搭建 使用安装包安装IDF 可以通过安装包进行安装,如下图: 下载链接如下:https://dl.espressif.cn/dl/esp-idf/?idf4.4 安装好后,IDF会添加环境变量IDF_TOOLS_PATH,如果要安装多个IDF,为了防止冲…...
伦敦金的走势高低的规律
伦敦金市场是一个流动性很强的市场,其价格走势会在诸多因素的影响下,出现反复的上下波动,如果投资者能够在这些高低走势中找到一定的规律,在相对有利的时机入场和离场,就能够通过不断的交易,累积大量的财富…...
【C#-1】C#调用matlab生成的dll库
matlab打包dll 1、matlab示例程序: function untitled4(x)z peaks(x);figuresurf(z) end 2、输入deploytool打包matlab程序,具体如下: 3、拷贝 打包成功后,将生成for_redistribution_files_only文件夹中的dll文件拷贝到C#程序…...
MATLAB中pdist和pdist2的区别
一、pdist 和 pdist2 是MATLAB中用于计算距离矩阵的两个不同函数,它们的区别在于输入和输出以及一些计算选项。 pdist: pdist函数用于计算一组点之间的距离。 输入:通常接受一个矩阵,矩阵的每一行代表一个数据点,矩阵的列代表数据…...
直播平台源码开发搭建APP的DASH协议:流媒体技术其中一环
在直播平台源码APP中,有着许许多多、多种多样的功能,比如短视频功能,帮助我们去获取信息,看到全世界用户身边发生的事情或是他们的生活;又比如直播功能,为用户提供了实时的娱乐享受,还让一些用户…...
【前端】js解码base64
【前端】js解码base64 //不会乱码 function strTob(base64) {// 对base64转编码var decode atob(base64)decode escape(decode)// 编码转字符串var str decodeURIComponent(decode)return str } atob 中文乱码的解决方案 decode escape(decode) // 编码转字符串 v…...
Apipost:API开发者的协同工作神器
在当今快速发展的数字化时代,API已成为企业与开发者实现数据互通、应用集成的重要桥梁。然而,随着API数量的不断增加,API开发、调试、测试、文档等工作也变得越来越复杂。为了解决这一痛点,一款名为Apipost的API协同研发工具应运而…...
照片动起来软件有哪些?试试这几个
照片动起来软件有哪些?将照片动起来可以让照片更加生动有趣,让人们更容易吸引到你的照片。在社交媒体和短视频的时代,人们需要更多的方式来吸引别人的注意力。让照片动起来可以让你的照片变得更加生动、更加有趣,让人们更容易停留…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
数据挖掘是什么?数据挖掘技术有哪些?
目录 一、数据挖掘是什么 二、常见的数据挖掘技术 1. 关联规则挖掘 2. 分类算法 3. 聚类分析 4. 回归分析 三、数据挖掘的应用领域 1. 商业领域 2. 医疗领域 3. 金融领域 4. 其他领域 四、数据挖掘面临的挑战和未来趋势 1. 面临的挑战 2. 未来趋势 五、总结 数据…...
【R语言编程——数据调用】
这里写自定义目录标题 可用库及数据集外部数据导入方法查看数据集信息 在R语言中,有多个库支持调用内置数据集或外部数据,包括studentdata等教学或示例数据集。以下是常见的库和方法: 可用库及数据集 openintro库 该库包含多个教学数据集&a…...
