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

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);}}

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

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

相关文章

苦瓜书盘官网,免费pdf/mobi电子书下载网站

苦瓜书盘&#xff08;kgbook&#xff09;是一个专注于提供6英寸PDF和MOBI格式电子书的免费下载平台&#xff0c;专为电子阅读器用户设计。该平台为用户提供了丰富的电子书资源&#xff0c;涵盖文学、历史、科学、技术等多个领域&#xff0c;旨在打造一个全面的电子书资源库。用…

PPT 小黑第20套

对应大猫21 Word转PPT 图片也得复制 题目要求两套PPT母板&#xff0c;应用不同版式&#xff08;版式那就可以选&#xff09; 竖排文字

第六课:数据库集成:MongoDB与Mongoose技术应用

本文详细介绍了如何在Node.js应用程序中集成MongoDB数据库&#xff0c;并使用Mongoose库进行数据操作。我们将涵盖MongoDB在Ubuntu 20系统中的安装、Bash命令的CRUD操作、Mongoose数据建模&#xff08;Schema/Model&#xff09;、关联查询与聚合管道&#xff0c;以及实战案例—…

蓝桥云客 卡牌

2.卡牌 - 蓝桥云课 卡牌 问题描述 这天&#xff0c;小明在整理他的卡牌。 他一共有n种卡牌&#xff0c;第i种卡牌上印有正整数i(i∈[1,n])&#xff0c;且第i种卡牌现有a_i张。 而如果有n张卡牌&#xff0c;其中每种卡牌各一张&#xff0c;那么这n张卡牌可以被称为一套牌。小…

【Linux】——初识操作系统

文章目录 冯-诺依曼体系结构操作系统shell 冯-诺依曼体系结构 我们现在所使用的计算机就是冯-诺依曼体系结构。 存储器就是内存。 由下图可知&#xff0c;寄存器最快&#xff0c;为啥不用寄存器呢&#xff1f; 因为越快价格就最贵&#xff0c;冯诺依曼体系结构的诞生&#xf…

坐标变换介绍与机器人九点标定的原理

【备注】本文的C#代码在下面链接中可以下载:Opencv的C#九点标定代码资源-CSDN文库 https://download.csdn.net/download/qq_34047402/90452336 一、坐标变换的介绍 1.绕原点旋转的坐标变换 一个点(x,y)绕原点旋转u度,其旋转后的坐标(x1,y1)如何计算? 2.绕任意点的坐标变…

恶劣天候三维目标检测论文列表整理

恶劣天候三维目标检测论文列表 图摘自Kradar &#x1f3e0; 介绍 Hi&#xff0c;这是有关恶劣天气下三维目标检测的论文列表。主要是来源于近3年研究过程中认为有意义的文章。希望能为新入门的研究者提供一些帮助。 可能比较简陋&#xff0c;存在一定的遗漏&#xff0c;欢迎…

掌握Kubernetes Network Policy,构建安全的容器网络

在 Kubernetes 集群中&#xff0c;默认情况下&#xff0c;所有 Pod 之间都是可以相互通信的&#xff0c;这在某些场景下可能会带来安全隐患。为了实现更精细的网络访问控制&#xff0c;Kubernetes 提供了 Network Policy 机制。Network Policy 允许我们定义一组规则&#xff0c…

Mybatis集合嵌套查询,三级嵌套

三个表&#xff1a;房间 玩家 玩家信息 知识点&#xff1a;Mybatis中级联有关联&#xff08;association&#xff09;、集合&#xff08;collection&#xff09;、鉴别器&#xff08;discriminator&#xff09;三种。其中&#xff0c;association对应一对一关系、collectio…

字典树(trie树)详解

【本文概要】本文主要介绍了字典树的概念&#xff0c;字典树的一般算法&#xff0c;包括初始化&#xff0c;插入&#xff0c;查找等&#xff0c;最后举了比较典型的案例以及算法比赛中常见的“01树”来辅助理解字典树这种特殊的数据结构。 1、什么是字典树 字典树&#xff0c;是…

【html期末作业网页设计】

html期末作业网页设计 作者有话说项目功能介绍 网站结构完整代码网站样图 作者有话说 目前&#xff0c;我们的项目已经搭建了各页面的基本框架&#xff0c;但内容填充还不完善&#xff0c;各页面之间的跳转逻辑也还需要进一步优化。 我们深知&#xff0c;一个好的项目需要不断…

数据安全VS创作自由:ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南

文章目录 数据安全VS创作自由&#xff1a;ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南ChatGPTKimi腾讯元宝DeepSeek 数据安全VS创作自由&#xff1a;ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南 产品隐私设置操作路径隐私协议ChatGPT…

C语言实现贪吃蛇

贪吃蛇小游戏的实现 讲解1.Win32 API介绍1.1控制台程序(system())1.2控制台屏幕上的坐标CDDRD1.3 GetStdHandle1.4 GetConsoleCursorInfo1.5 SetConsoleCursorInfo1.6 SetConsoleCursorPostion1.7 GetAsyncKeyState 2.游戏设计2.1地图2.2蛇身和食物2.3数据结构设计2.4游戏流程设…

游戏引擎学习第142天

今天的计划 欢迎来到这个游戏开发项目&#xff0c;我们将从零开始编写一个完整的游戏&#xff0c;并且不会使用任何现成的库或引擎。整个开发过程中涉及的所有代码都会被完整展示&#xff0c;包括游戏运行所需的每一个细节。无论是哪款游戏&#xff0c;最终都需要有人编写底层…

Manus全球首个通用Agent,Manus AI:Agent应用的ChatGPT时刻

文章目录 前言Manus AI: 全球首个通用AgentManus AI: 技术架构与创始人经历AI Agent的实现框架与启示AI Agent的发展预测行业风险提示 前言 这是一篇关于Manus AI及其在通用人工智能领域的应用和前景的报告&#xff0c;主要介绍了Manus AI的产品定位、功能、技术架构、创始人经…

FPGA学习篇——Verilog学习3(关键字+注释方法+程序基本框架)

1 Verilog常用关键字 大概知道以下哪些是关键字就好&#xff0c;如何使用还是得在编写代码中来学习。 2 Verilog注释方法 Verilog有两种注释方式&#xff1a; 2.1 “ // ” 单行。 2.2 “ /* ... */ ” 可扩展多行。 3 Verilog程序基本框架 Verilog 的基本设计单元是“…

一文对比RAGFLOW和Open WebUI【使用场景参考】

一、RAGFLOW与Open WebUI RAGFLOW是一款基于深度文档理解构建的开源 RAG&#xff08;Retrieval-Augmented Generation&#xff09;引擎。RAGFlow 可以为各种规模的企业及个人提供一套精简的 RAG 工作流程&#xff0c;结合大语言模型&#xff08;LLM&#xff09;针对用户各类不…

SyntaxError: Missing semicolon

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…

游戏引擎学习第140天

回顾并为今天的内容做准备 目前代码的进展到了声音混音的部分。昨天我详细解释了声音的处理方式&#xff0c;声音在技术上是一个非常特别的存在&#xff0c;但在游戏中进行声音混音的需求其实相对简单明了&#xff0c;所以今天的任务应该不会太具挑战性。 今天我们会编写一个…

vue3如何配置环境和打包

很多新手友友们或刚从vue2切换到vue3的同学&#xff0c;对vue3不同环境配置和打包有很多困惑的地方&#xff0c;Jenna这就把vue3打包配置流程详细的写下来&#xff0c;你们只需要copy就好啦 1.创建环境文件 当我们把项目拿到手&#xff0c;只需要创建三个环境文件&#xff1a…