单链表-java

此次我们主要通过数组来模拟一下单链表,并完成一些基本的功能。

文章目录

前言

一、单链表

二、思路模拟

1.引入变量解释

2.链表初始化

3.在头结点后插入一个结点

4.表示在第k个数后面插入一个数

5. 把第k个数后面的一个数删除掉

三、代码如下

1.代码如下:

2.读入数据

3.代码运行结果

总结


前言

此次我们主要通过数组来模拟一下单链表,并完成一些基本的功能。


一、单链表

实现一个单链表,链表初始为空,支持三种操作:

  1. 向链表头插入一个数;
  2. 删除第 k 个插入的数后面的一个数;
  3. 在第 k个插入的数后插入一个数。

现在要对该链表进行 M次操作,进行完所有操作后,从头到尾输出整个链表。

注意:题目中第 k个插入的数并不是指当前链表的第 k 个数。例如操作过程中一共插入了 n 个数,则按照插入的时间顺序,这 n个数依次为:第 1个插入的数,第 2个插入的数,…第 n个插入的数。

输入格式

第一行包含整数 M,表示操作次数。

接下来 M 行,每行包含一个操作命令,操作命令可能为以下几种:

  1. H x,表示向链表头插入一个数 x。
  2. D k,表示删除第 k 个插入的数后面的数(当 k 为 00 时,表示删除头结点)。
  3. I k x,表示在第 k 个插入的数后面插入一个数 x(此操作中 k 均大于 00)。

输出格式

共一行,将整个链表从头到尾输出。

数据范围

1≤M≤100000
所有操作保证合法。

二、思路模拟

1.引入变量解释

图1.1 数组模拟单链表

我们引入一个整型head,来表示头结点(第一个结点)的下标;引入一维整型数组e,用来存储结点的值;一个整型index,用来表示当前数组e第一个没有存储值的下标(即第一个空结点的下标),或者是我们新存入结点,index就是新存入结点在e数组的下标;用一个一维整型数组ne,用来存储当前结点指向的下一个结点(假设3结点指向5结点)即5结点在数组e中的下标(如图1.1)。

2.链表初始化

head的初始值为-1,此时表示该链表为空,没有存储任何值;

index的初始值为0,表示空链表,即第一个结点就是空的。

    //初始化public static void init(){head = -1;index = 0;}

3.在头结点后插入一个结点

图3.1思路模拟 

我们新插入的结点值是x,那么我们先创建一个结点即e[index] = x;然后我们需要将新结点指向头结点原本指向的结点,原本头结点的下标就是head,而ne[index]就是新结点要指向下一个结点的下标,那么我们要进行即ne[index] = head;然后我们要让头指针指向新结点,即head = index,即此时的头结点的下标就是我们新插入结点的下标。最后切记index++,因为我们index表示的是在e数组中第一个空的结点的下标,那么我们用了一个结点,我们就是让index后移一位,让index指向的结点仍是空的。

    //将x插入头结点后面public static void addHead(int x){e[index] = x;ne[index] = head;head = index;index++;}

4.表示在第k个数后面插入一个数

图4.1思路模拟 

这个操作我们可以转换成在指定下标的结点后面插入一个结点的操作。(注意图中的k是结点的下标)我们将新插入的结点赋值为x即e[index] = x,然后我们需要让新结点指向下标为k的结点指向的下一个结点,此时下标为k的结点指向的下一个结点就是ne[k],那么我们需要进行e[index] = ne[k],此时我们新结点就指向原本下标为k结点所指向的下一个结点。最后我们还要让下标为k的结点指向新结点,下标为k的结点指向的下一个结点的下标为ne[k],那么我们就需要让ne[k] = index,此时我们就完成了将新结点插入整个链表。最后切记让index++,还是为了index指向的结点仍是空的。

    //将x插入到下标是k的结点后面public static void add(int x,int k){e[index] = x;ne[index] = ne[k];ne[k] = index;index++;}

5. 把第k个数后面的一个数删除掉

图5.1思路模拟 

我们可以转化为删除指定下标结点的后面一个结点。假设我们要删除下标为k的结点的后面一个结点,那么我们需要让结点k指向它的下一个结点指向的下一个结点,结点k指向的下一个结点为ne[k],我们假设这个结点的下标为m,那么m = ne[k]。然后m指向的下一个结点为ne[m]。我们的删除操作就是让结点k直接指向m指向的下一个结点,即ne[k] = ne[m],最后我们可以写成ne[k] = ne[ne[k]]。此时我们就完成了删除操作。

    //将下标为k的结点后面的结点删掉public static void remove(int k){ne[k] = ne[ne[k]];}

当我们删除第0个插入的数后面一个数,传入的下标k = 0 - 1发生数组越界,我们需要特殊处理一下 ,即删除头节点,那我们就需要将头指针后移,就是将头结点的索引head,改为头结点的下一个结点即ne[head],那么我们进行head = ne[head]即可。

            //删除下标为k-1结点的后一个结点else if (cmd.equals("D")) {k = Integer.parseInt(str[1]);if(k != 0){remove(k-1);}//表示删除头结点,头指针后移else {head = ne[head];}}

注:当这个结点的下一个结点的索引是-1时,就说明这就是最后一个结点。 

三、代码如下

1.代码如下:


import java.io.*;
import java.util.*;public class 单链表 {static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static int N = 1000010;//表示第一个结点的下标static int head;//存储结点值static int[] e = new int[N];//存储下一个结点的下标static int[]ne = new int[N];//指针,e数组最新空的元素的下标static int index;public static void main(String[] args) {Scanner sc = new Scanner(br);init();int m = Integer.parseInt(sc.nextLine());while (m-- > 0){int k,x;String[] str = sc.nextLine().split(" ");String cmd = str[0];//向链表头插入一个结点if(cmd.equals("H")){x = Integer.parseInt(str[1]);addHead(x);}//删除下标为k-1结点的后一个结点else if (cmd.equals("D")) {k = Integer.parseInt(str[1]);if(k != 0){remove(k-1);}//表示删除头结点,头指针后移else {head = ne[head];}}//在下标为k-1的结点后面插一个结点else if (cmd.equals("I")) {k = Integer.parseInt(str[1]);x = Integer.parseInt(str[2]);add(k-1,x);}}//打印链表for(int i = head;i != -1;i = ne[i]){pw.print(e[i]+" ");}pw.flush();}//初始化public static void init(){head = -1;index = 0;}//将x插入头结点后面public static void addHead(int x){e[index] = x;ne[index] = head;head = index;index++;}//将x插入到下标是k的结点后面public static void add(int k,int x){e[index] = x;ne[index] = ne[k];ne[k] = index;index++;}//将下标为k的结点后面的结点删掉public static void remove(int k){ne[k] = ne[ne[k]];}
}

2.读入数据

10
H 9
I 1 1
D 1
D 0
H 6
I 3 6
I 4 5
I 4 5
I 3 4
D 6

3.代码运行结果

6 4 6 5 

总结

上午主要通过数组来模拟单链表,关键通过对各个变量知道什么意思,明白增删操作是怎样进行的,看一下图示和文字描述加强一下理解。

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

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

相关文章

NDK 入门(二)—— 调音小项目

NDK 入门系列主要介绍 JNI 的相关内容,目录如下: NDK 入门(一)—— JNI 初探 NDK 入门(二)—— 调音小项目 NDK 入门(三)—— JNI 注册与 JNI 线程 NDK 入门(四&#xff…

数字滤波器设计笔记1

系统结构 1.先利用matlab的simulink和FDA进行滤波器建模设计,通过仿真后,确定模型达到相应的性能要求,再利用verilog进行电路设计。最后使用modelsim进行功能验证。其中testbench的输入数据,利用matlab模型的输入数据。 2.Matlab…

最最普通程序员,如何利用工资攒够彩礼,成为人生赢家

今天我们不讲如何提升你的专业技能去涨工资,不讲面试技巧如何跳槽涨工资,不讲如何干兼职赚人生第一桶金,就讲一个最最普通的程序员,如何在工作几年后,可以攒够彩礼钱,婚礼酒席钱,在自己人生大事…

pytho爬取南京房源成交价信息并导入到excel

# encoding: utf-8 # File_name: import requests from bs4 import BeautifulSoup import xlrd #导入xlrd库 import pandas as pd import openpyxl# 定义函数来获取南京最新的二手房房子成交价 def get_nanjing_latest_second_hand_prices():cookies {select_city: 320100,li…

信息系统项目管理师——第5章信息系统工程(一)

近几期的考情来看,本章选择题稳定考4分,考案例的可能性有,需要重点学习。本章节专业知识点特别多。但是,只考课本原话,大家一定要把本章至少通读一遍,还要多刷题,巩固重点知识。 1 软件工程 软…

deepin 开源之夏重磅来袭!超优质项目已上线,欢迎来战

内容来源:deepin 社区 「开源之夏」是由中国科学院软件研究所“开源软件供应链点亮计划”发起并长期支持的一项暑期开源活动,旨在鼓励在校学生积极参与开源软件的开发维护,培养和发掘更多优秀的开发者,促进优秀开源软件社区的蓬勃…

javamail发送qq邮箱失败案例分析

文章目录 javaMail报错:Unsupported or unrecognized SSL message原因分析: ssl与tls端口总结 javaMail报错:Unsupported or unrecognized SSL message c.n.m.service.impl.EmailServiceImpl : 邮件发送异常, Mail server connection failed; nested exception is javax.m…

Spring AI 来啦,快速上手

Spring AI Spring框架在软件开发领域,特别是在Java企业级应用中,一直扮演着举足轻重的角色。它以其强大的功能和灵活的架构,帮助开发者高效构建复杂的应用程序。而Spring Boot的推出,更是简化了新Spring应用的初始搭建和开发过程…

【分治算法】【Python实现】棋盘覆盖

文章目录 [toc]问题描述分治算法时间复杂性Python实现 个人主页:丷从心 系列专栏:分治算法 学习指南:Python学习指南 问题描述 在一个 2 k 2 k 2^{k} \times 2^{k} 2k2k个方格组成的棋盘中,若恰有一个方格与其他方格不同&…

httpClient提交报文中文乱码

httpClient提交中文乱码,ContentType类型application/json 指定提交参数的编码即可 StringEntity se new StringEntity(paramBody.toJSONString(),"UTF-8");se.setContentType("application/json");context.httpPost.setHeader("Cookie&…

JUC并发-共享模型-无锁-乐观锁(非阻塞)

1、问题提出 有如下需求,保证 account.withdraw 取款方法的线程安全 public class TestAccount {public static void main(String[] args) {Account account new AccountCas(10000);Account.demo(account);} }class AccountUnsafe implements Account {private I…

2024LarkXR新增功能系列之五 | 单端口支持多并发

实时云渲染技术在为虚拟现实、游戏、和各种应用程序提供强大的渲染支持的同时,也带来了一些网络和运维上的挑战。在传统的设置中,实时云渲染推流技术需要为每个视频流单独占用服务器的一个端口。这种方法在多用户同时访问的情况下可能会导致端口资源的快…

MemFire解决方案-物联网数据平台解决方案

方案背景 随着各种通讯、传感技术发展,数据通讯成本的急剧下降,数以万亿计的智能设备(智能手环、智能电表、智能手机、各种传感器设备等)接入网络,并源源不断的产生海量的实时数据。这些海量数据的价值挖掘&#xff0…

Node私库Verdaccio使用记录,包的构建,推送和拉取

Node私库Verdaccio使用记录,包的构建,推送和拉取 Verdaccio是一个轻量级的私有npm代理注册中心,它可以帮助你在本地搭建一个npm仓库,非常适合企业内部使用。通过使用Verdaccio,你可以控制和缓存依赖包,提高…

边OTG边充电芯片LDR6500

随着科技的飞速发展,智能移动设备已成为我们生活中不可或缺的一部分。而在这些设备的连接与数据传输中,Type-C接口以其高效、便捷的特性逐渐占据了主导地位。OTG(On-The-Go)技术则进一步扩展了Type-C接口的功能,使得设…

构建安全高效的数字货币钱包:开发指南

在加密货币领域的蓬勃发展中,数字货币钱包成为了连接用户与区块链的重要桥梁。作为存储、发送和接收加密资产的工具,数字货币钱包的安全性和效率至关重要。本文将介绍如何构建一个安全高效的数字货币钱包,并提供开发指南,帮助开发…

2024中国(江西)国际先进陶瓷材料及智能装备博览会

2024中国(江西)国际先进陶瓷材料及智能装备博览会 “中国(江西)国际先进陶瓷材料及智能装备博览会” 陶瓷三新展 (新材料、新装备、新技术) 绿色智能、引领未来 2024年11月1日-11月3日 中国江西 南昌…

深度学习系列64:数字人wav2lip详解

1. 整体流程 第一步,加载视频/图片和音频/tts。用melspectrogram将wav文件拆分成mel_chunks。 第二步,调用face_detect模型,给出人脸检测结果(可以改造成从文件中读取),包装成4个数组batch:img…

html显示PDF并兼容IE浏览器的解决方案

方案一、vue-pdf插件 缺点&#xff1a;IE11显示空白&#xff0c;编译后的Edge测试环境可以正常线上&#xff0c;打到线上报错&#xff0c;谷歌和百分浏览器显示完美 1、vue 只显示核心代码&#xff0c;需要安装vue-pdf插件 <vue-pdf :src"ivcPdfUrl"></v…

Spring声明式事务(@Transactional)原理之-ProxyTransactionManagementConfiguration

文章目录 目录 文章目录 前言 一、切入点以及切面的匹配规则 1.1 TransactionAttributeSourcePointcut事务的切入点匹配 二、TransactionInterceptor切面的具体逻辑 2.1 声明式事务实现的具体逻辑 总结 前言 上一篇文章已经说过了声明式事务的原理其实就是SpringAop动态…