当前位置: 首页 > news >正文

数据结构——顺序表与链表

1. 基础介绍

1、线性结构:

如果一个数据元素序列满足:

(1)除第一个和最后一个数据元素外,每个数据元素只有一个前驱数据元素和一个后继数据元素;

(2)第一个数据元素没有前驱数据元素;

(3)最后一个数据元素没有后继数据元素。

则称这样的数据结构为线性结构。

2. 线性表

线性表 (linear list) 是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中⼴泛使⽤ 的数据结构,常⻅的线性表:顺序表、链表、栈、队列。
线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储

3. 顺序表

顺序表是⽤⼀段物理地址连续的存储单元依次存储数据元素的线性结构,⼀般情况下采⽤数组存储。在数组上完成数据的增删查改。

2. List介绍

1. list(线性表)

在集合框架中,List是⼀个接⼝,继承⾃Collection
Collection也是⼀个接⼝,该接⼝中规范了后序容器中常⽤的⼀些⽅法。
方法解释
boolean add (E e)
尾插 e
void add (int index, E element)
e 插入到 index 位置
boolean addAll(Collection<? extends E> c)尾插 c 中的元素
E remove(int index)
删除 index 位置元素
boolean remove(Object o)删除遇到的第一个 o,传入的是一个对象
E get (int index)
获取下标 index 位置元素
E set (int index, E element)
将下标 index 位置元素设置为 element
void clear ()
清空
boolean contains(Object o)判断 o 是否在线性表中
int indexOf(Object o)返回第一个 o 所在下标
int lastIndexOf(Object o)返回最后一个 o 的下标
List<E> subList(int fromIndex, int toIndex)截取部分list,前开后闭
        List<Integer> list1 = new LinkedList<>();list1.add(1);list1.add(2);list1.add(3);list1.add(4);list1.add(5);//当我们想删除2这个元素list1.remove(new Integer(5));System.out.println(list1);List<Integer> list3 = list1.subList(1,3);//截取[1,3)list3.set(0,188);System.out.println(list3);System.out.println(list1);

为什么改变 list3 中的值,list1 也会改变?

2. ArrayList(顺序表)

方法解释
ArrayList ()
无参构造
ArrayList(Collection<? extends E> c)利用其他 Collection 构建 ArrayList
ArrayList(int initialCapacity)指定顺序表初始容量

ArrayList(Collection<? extends E> c):

能够引用的类一定是E或E的子类

    public static void main(String[] args) {List<Integer> list1 = new LinkedList<>();//LinkedList是List接口的一个实现类,它使用链表数据结构来存储元素list1.add(1);list1.add(2);list1.add(3);List<Integer> list = new ArrayList<>(list1);//将list1中的所有元素复制到新的ArrayList中list.add(1314);System.out.println(list);}

3. Linkedlist(链表)
方法解释
LinkedList()无参构造
List 的官方文档:    List (Java Platform SE 8 )
ArrayList 的官方文档:      ArrayList (Java Platform SE 8 )
LinkedList 的官方文档:     LinkedList (Java Platform SE 8 )

3. ArrayList介绍

在集合框架中,ArrayList是⼀个普通的类,实现了List接⼝,具体框架图如下:
【说明】
1. ArrayList是以泛型⽅式实现的,使⽤时必须要先实例化
2. ArrayList实现了RandomAccess接⼝,表明ArrayList⽀持随机访问
3. ArrayList实现了Cloneable接⼝,表明ArrayList是可以clone的
4. ArrayList实现了Serializable接⼝,表明ArrayList是⽀持序列化的
5. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使⽤,在多线程中可以选择Vector或者CopyOnWriteArrayList
6. ArrayList底层是⼀段连续的空间,并且可以动态扩容,是⼀个动态类型的顺序表

 底层扩容

迭代器
一般情况下,能够直接通过 sout 输出引用指向对象当中的内容的时候,此时一定重写了 toString 方法
导入包    : import java.util.Iterator;
 ArrayList<Integer> list2 = new ArrayList<>();list2.add(10);list2.add(20);list2.add(30);list2.add(40);System.out.println(list2);//一般情况下,能够直接通过 sout 输出引用指向对象当中的内容的时候,此时一定重写了 toString 方法System.out.println("===================");//迭代器//方法1:Iterator<Integer> it = list2.iterator();//判断下一个数据是否存在while (it.hasNext()){System.out.print(it.next()+" ");//打印it的下一个数据}System.out.println();System.out.println("===================");//方法2:ListIterator<Integer> it2 = list2.listIterator();//判断下一个数据是否存在while (it2.hasNext()){System.out.print(it2.next()+" ");//打印it2的下一个数据}System.out.println();System.out.println("===================");

如果我们想逆序打印呢

        //逆序打印ListIterator<Integer> it3 = list2.listIterator(list2.size());//判断上一个数据是否存在while (it3.hasPrevious()){System.out.print(it3.previous()+" ");//打印it3的上一个数据}System.out.println();System.out.println("===================");

         

List<List<E>>  list = new ArrayList<>();

这种结构在Java中表示一个包含多个列表的列表

List<List<E>>: 这是一个泛型声明,表示一个列表的列表。外层列表的每个元素都是一个List<E>,即一个包含类型为E的元素的列表。

ArrayList的问题及思考:
1. ArrayList底层使⽤连续的空间,任意位置插⼊或删除元素时,需要将该位置后序元素整体往前或者往后搬移,故时间复杂度为O(N)
2. 增容需要申请新空间,拷⻉数据,释放旧空间。会有不⼩的消耗。
3. 增容⼀般是呈1.5倍的增⻓,势必会有⼀定的空间浪费。

4. 链表介绍

链表是⼀种 物理存储结构上⾮连续 存储结构,数据元素的逻辑顺序是通过链表中的引⽤链接次序实现的 。
区别ArrayListLinkedList

内部实现

  • 基于动态数组实现。

  • 底层使用一个数组来存储元素,当数组容量不足时,会自动扩容(通常是当前容量的1.5倍)。

  • 适合随机访问(通过索引访问元素)。

  • 基于双向链表实现。

  • 每个元素是一个节点,包含数据和指向前后节点的指针。

  • 适合频繁的插入和删除操作。

随机访问通过索引访问元素的时间复杂度为 O(1),非常高效。通过索引访问元素的时间复杂度为 O(n),需要从头或尾遍历链表。
插入和删除
  • 在数组末尾插入或删除元素的时间复杂度为 O(1)

  • 在数组中间插入或删除元素的时间复杂度为 O(n),因为需要移动后续元素。

  • 在链表头部或尾部插入或删除元素的时间复杂度为 O(1)

  • 在链表中间插入或删除元素的时间复杂度为 O(n),因为需要遍历链表找到目标位置。

内存占用内存占用相对较小,因为底层是连续的数组。内存占用相对较大,因为每个节点需要额外存储前后指针

适用场景

  • 适合频繁的随机访问操作。

  • 适合在数组末尾频繁插入和删除元素。

  • 适合存储大量数据,且数据量相对固定。

  • 适合频繁的插入和删除操作,尤其是在链表头部或尾部。

  • 适合实现队列(Queue)或双端队列(Deque)。

  • 适合数据量变化较大的场景。

总结

  • ArrayList

    • 优点:随机访问高效,内存占用小。

    • 缺点:插入和删除操作(尤其是中间位置)较慢。

    • 适用场景:频繁随机访问,数据量相对固定。

  • LinkedList

    • 优点:插入和删除操作(尤其是头部和尾部)高效。

    • 缺点:随机访问较慢,内存占用大。

    • 适用场景:频繁插入和删除操作,数据量变化较大。

简单的洗牌算法

import java.util.ArrayList;
import java.util.List;
import java.util.Random;public class CardDom {static class Card{public int rank;//牌面值public String suit;//花色public Card(int rank,String suit){this.rank = rank;this.suit = suit;}@Overridepublic String toString() {return "["+rank + " "+ suit+"]" ;}}public static final String[] SUITS = {"♠","♥","♣","♦"};//有一副牌private static List<Card> buyDeck(){List<Card> deck = new ArrayList<>();//创建一个链表存放牌for(int i=0;i<SUITS.length;i++){for(int j=1;j<=13;j++){Card card = new Card(j,SUITS[i]);deck.add(card);//将牌插入}}return deck;}//将交换牌的位置private static void swap(List<Card> deck, int i, int j){Card t = deck.get(i);deck.set(i,deck.get(j));deck.set(j,t);}//洗牌private static void shuffle(List<Card> deck){Random random = new Random();for(int i=deck.size()-1;i>0;i--){int j = random.nextInt(i);swap(deck,i,j);}}//每人发五张牌public static void main(String[] args) {List<Card> desk = buyDeck();System.out.print("买回来的牌:");System.out.println(desk);shuffle(desk);System.out.print("洗过的牌:");System.out.println(desk);List<List<Card>> heads = new ArrayList<>();//三个人玩牌List<Card> head0 = new ArrayList<>();//存放第一个人的牌List<Card> head1 = new ArrayList<>();//存放第二个人的牌List<Card> head2 = new ArrayList<>();//存放第三个人的牌heads.add(head0);heads.add(head1);heads.add(head2);//控制次数for(int i=0;i<5;i++){for (int j=0;j<3;j++){//每次拿零下标的牌Card card=desk.remove(0);//从牌中拿出第一张牌heads.get(j).add(card);//每个人拿到的牌存入对应的顺序表}}System.out.print("第一个人拿的牌");System.out.println(head0);System.out.print("第二个人拿的牌");System.out.println(head1);System.out.print("第三个人拿的牌");System.out.println(head2);System.out.print("剩下的牌:");System.out.println(desk);}}

相关文章:

数据结构——顺序表与链表

1. 基础介绍 1、线性结构&#xff1a; 如果一个数据元素序列满足&#xff1a; &#xff08;1&#xff09;除第一个和最后一个数据元素外&#xff0c;每个数据元素只有一个前驱数据元素和一个后继数据元素&#xff1b; &#xff08;2&#xff09;第一个数据元素没有前驱数据…...

【uniapp】图片添加canvas水印

目录 需求&背景实现地理位置添加水印 ios补充 需求&背景 需求&#xff1a;拍照后给图片添加水印, 水印包含经纬度、用户信息、公司logo等信息。 效果图&#xff1a; 方案&#xff1a;使用canvas添加水印。 具体实现&#xff1a;上传图片组件是项目里现有的&#xff…...

ElementUI 级联选择器el-cascader启用选择任意一级选项,选中后关闭下拉框

1、启用选择任意一级选项 在 el-cascader 标签上加上配置项&#xff1a; :props"{ checkStrictly: true }"例如&#xff1a; <el-cascaderref"selectedArrRef"v-model"selectedArr":options"optionsList":props"{ checkStri…...

【音视频】ffplay常用命令

一、 ffplay常用命令 -x width&#xff1a;强制显示宽度-y height&#xff1a;强制显示高度 强制以 640*360的宽高显示 ffplay 2.mp4 -x 640 -y 360 效果如下 -fs 全屏显示 ffplay -fs 2.mp4效果如下&#xff1a; -an 禁用音频&#xff08;不播放声音&#xff09;-vn 禁…...

5人3小时复刻Manus?开源OpenManus项目全解剖,我的DeepSeek股票报告这样诞生

大家好,我是大 F,深耕AI算法十余年,互联网大厂技术岗。分享AI算法干货、技术心得。 更多文章可关注《大模型理论和实战》、《DeepSeek技术解析和实战》,一起探索技术的无限可能! OpenManus是什么 1. 项目背景 OpenManus 是由 MetaGPT 核心团队仅用 3 小时复刻而成的开源…...

【Python运维】用Python自动化AWS资源管理:利用boto3实现高效管理S3桶和EC2实例

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着云计算的普及,AWS(Amazon Web Services)已经成为许多企业和开发者首选的云平台。为了提高工作效率,自动化管理AWS资源成为了一个热…...

django各种mixin用法

在 Django 中,Mixin 是一种用于扩展类功能的设计模式。通过 Mixin,可以在不修改原有类的情况下,为其添加新的方法或属性。Django 中的 Mixin 广泛应用于视图(View)、表单(Form)、模型(Model)等组件中。以下是 Django 中常见 Mixin 的用法和示例: 一、视图(View)中的…...

Java 大视界 -- Java 大数据在智能教育考试评估与学情分析中的应用(112)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

Manus AI : Agent 元年开启.pdf

Manus AI : Agent 元年开启.pdf 是由华泰证券出品的一份调研报告&#xff0c;共计23页。报告详细介绍了Manus AI 及 Agent&#xff0c;主要包括Manus AI 的功能、优势、技术能力&#xff0c;Agent 的概念、架构、应用场景&#xff0c;以及 AI Agent 的类型和相关案例&#xff0…...

【计算机网络】计算机网络的性能指标——时延、时延带宽积、往返时延、信道利用率

计算机网络的性能指标 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在上一篇内容中我们介绍了计算机网络的三个性能指标——速率、带宽和吞吐量。用大白话来说就是&#xff1a;网速、最高网速和实时网速。 相信大家看到这三个词应该就…...

FreeRTOS第15篇:FreeRTOS链表实现细节03_List_t与ListItem_t的奥秘

文/指尖动听知识库-星愿 文章为付费内容,商业行为,禁止私自转载及抄袭,违者必究!!! 文章专栏:深入FreeRTOS内核:从原理到实战的嵌入式开发指南 1 FreeRTOS列表的核心数据结构 FreeRTOS的列表实现由两个关键结构体组成:List_t(列表)和ListItem_t(列表项)。它们共同…...

git 添加额外的远程仓库 URL

要使用 git branch -a 查看 net-next 远程仓库中的所有分支&#xff0c;请按照以下步骤操作&#xff1a; 步骤 1: 确保已添加 net-next 远程仓库 如果尚未添加 net-next 远程仓库&#xff0c;请运行以下命令&#xff1a; git remote add net-next git://git.kernel.org/pub/s…...

不同类型光谱相机的技术差异比较

一、波段数量与连续性 ‌多光谱相机‌ 波段数&#xff1a;通常4-9个离散波段&#xff0c;光谱范围集中于400-1000nm‌。 数据特征&#xff1a;光谱呈阶梯状&#xff0c;无法连续覆盖&#xff0c;适用于中等精度需求场景&#xff08;如植被分类&#xff09;‌。 ‌高光谱相机…...

Swift系列01-Swift语言基本原理与设计哲学

本文将深入探讨Swift的核心原理、设计理念以及与Objective-C的对比 1. Swift与Objective-C的架构差异分析 Swift和Objective-C尽管可以无缝协作&#xff0c;但它们的架构设计存在本质差异。 1.1语言范式 Objective-C是一种动态语言&#xff0c;建立在C语言之上并添加了Smal…...

《OpenCV》——dlib(人脸应用实例)

文章目录 dlib库dlib库——人脸应用实例——表情识别dlib库——人脸应用实例——疲劳检测 dlib库 dlib库的基础用法介绍可以参考这篇文章&#xff1a;https://blog.csdn.net/lou0720/article/details/145968062?spm1011.2415.3001.5331&#xff0c;故此这篇文章只介绍dlib的人…...

以太网通讯

接口开发笔记-WebApi-CSDN博客 以太网常用通讯协议 1、modbus tcp using EasyModbus; using System;class Program {static void Main(string[] args){// 创建Modbus客户端实例ModbusClient modbusClient new ModbusClient("192.168.1.100"); // IP地址modbusCli…...

UDP学习笔记(一)为什么UDP需要先将数据转换为字节数组

UDP 发送数据时需要先将数据转换为字节数组再发送&#xff0c;主要是因为计算机网络传输的最基本单位是“字节”&#xff08;Byte&#xff09;。让我们从以下几个方面来深入理解这个设计选择&#xff1a; 1. 计算机网络只能传输“字节” 在网络通信中&#xff0c;无论是 TCP 还…...

数据分析/数据科学常见SQL题目:连续登录用户、留存率、最大观看人数

文章目录 1. SQL的执行顺序是什么&#xff1f;on和join谁先执行&#xff0c;为什么&#xff1f;on和where的区别&#xff1f;2. 已知表user,字段id, date&#xff0c;求新用户的次日留存率3. 已知表user&#xff0c;字段id&#xff0c;date&#xff0c;求每个日期新用户的次日留…...

【Conda】Windows安装conda/Anaconda环境

安装conda并配置powershell 访问该网址&#xff0c;下载安装即可&#xff1a; Anaconda下载 安装完成后&#xff0c;打开Anaconda&#xff0c;并访问Powershell Prompt 弹出Windows Terminal&#xff0c;并正常进入Conda 【非必须】如果不是通过Windows Terminal打开&#x…...

olmOCR:高效精准的 PDF 文本提取工具

在日常的工作和学习中&#xff0c;是否经常被 PDF 文本提取问题困扰&#xff1f;例如&#xff1a; 想从学术论文 PDF 中提取关键信息&#xff0c;却发现传统 OCR 工具识别不准确或文本格式混乱&#xff1f;需要快速提取商务合同 PDF 中的条款内容&#xff0c;却因工具不给力而…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...