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

数据结构 顺序表与链表

文章目录

    • 📕1. 线性表(linear list)
    • 📕2. ArrayList与顺序表
        • ✏️2.1 顺序表的概念
        • ✏️2.2 ArrayList简介
        • ✏️2.3 ArrayList的构造
        • ✏️2.4 ArrayList常见操作
        • ✏️2.5 ArrayList的遍历
        • ✏️2.6 ArrayList的自动扩容机制
        • ✏️2.7 ArrayList常用方法的具体实现代码(重点!!!)
        • ✏️2.8 ArrayLsit当前面临的问题
    • 📕3. LinkedList与链表
        • ✏️3.1 链表的概念
        • ✏️3.2 LinkedList简介
        • ✏️3.3 LinkedList的构造
        • ✏️3.4 LinkedList常见操作
        • ✏️3.5 LinkedList常用方法的具体实现代码(重点!!!)
    • 📕4. ArrayList和LinkedList的区别

📕1. 线性表(linear list)

在集合框架中,List是一个接口。从数据结构的角度看,List就是一个线性表,即n个具有相同类型元素的有限序列,在该序列上可以执行增删改查以及变量等操作。

常见的线性表:顺序表、链表、栈、队列……

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储

线性结构规定:一个元素只能有一个前驱,一个后继。如果有多个前驱或后继,就不是线性结构。

💡注意:List是个接口,并不能直接用来实例化。

如果要使用,必须去实例化List的实现类。在集合框架中,ArrayList和LinkedList都实现了List接口。

ArrayList ⇒ 顺序表
LinkedList ⇒ 链表

📕2. ArrayList与顺序表

✏️2.1 顺序表的概念

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

✏️2.2 ArrayList简介

在集合框架中,ArrayList是⼀个普通的类,实现了List接口,具体框架图如下:
在这里插入图片描述

💡注意:

1. ArrayList是以泛型方式实现的,使用时必须要先实例化
2. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

✏️2.3 ArrayList的构造
方法解释
ArrayList()无参构造
ArrayList(int initialCapatity)指定顺序表初始容量
public static void main(String[] args) {List<Integer> l1 = new ArrayList<>(); //实例化一个空表,推荐写法List<Integer> l2 = new ArrsyList<>(10); //实例化一个初始容量为10的空表List<Integet> l3 = new ArrayList<>(l2); //实例化出的l3,与l2中的元素一致
}
✏️2.4 ArrayList常见操作

ArrayList虽然提供的方法比较多,但是常用方法如下所示,需要用到其他方法时,可以查看JAVA帮助手册。(可以我找要)

方法解释
boolean add(E e)尾插e
void add(int index,E e)把e插入到 index位置
E remove(int index)删除index位置的元素
E get(int index)获取index位置的元素
E set(int index,E e)将index位置元素设置为e
void clear()清空
boolean contains(Object o)判断o是否在线性表中
int indexof(Object o)返回第一的o所在的下标
int lastindexof(Object o)返回最后一个o所在下标

💡特别提醒:虽然ArrayList中提供了常见的方法,但是我们仍需掌握方法的底层原理。

✏️2.5 ArrayList的遍历

ArrayList可以使用三种方法进行遍历:

  1. for循环
public static void main(String[] args) {List<Integer> l1 = new ArrayList<>();l1.add(1);l1.add(2);l1.add(3);l1.add(4);l1.add(5);	l1.add(6);for(int i = 0;i<l1.size();i++){System.out.println(l1.get(i));}
}
  1. for-each
public static void main(String[] args) {List<String> l2 = new ArrayList<>();l2.add("1");l2.add("2");l2.add("3");l2.add("4");for (String l : l2){System.out.println(l);}
}

注意:并不是所有的类都能写进for-each循环中,写进for-each循环中的类要求必须实现Iterable接口

  1. 迭代器
public static void main(String[] args) {List<String> l3 = new ArrayList<>();l3.add("1");l3.add("2");l3.add("3");l3.add("4");Iterator<String> iterator = l3.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}}

ArrayList最常使用的遍历方式是:for循环 以及 foreach

✏️2.6 ArrayList的自动扩容机制

ArrayList内部持有一个数组,构造时设置的初始容量就是数组的大小,当ArrayList发现空间不够的时候,就会申请额外的空间,这就自动扩容机制。

自动扩容共有以下几步:

1. 发现空间不够之后,立刻创建一个更大的数组(为了防止申请空间过大浪费,ArrayList的策略是每次扩容为原来大小的1.5倍)
2. 把旧数组中的元素拷贝到新的数组中
3. 添加新的元素
4. 自动释放旧数组

✏️2.7 ArrayList常用方法的具体实现代码(重点!!!)

点击传送源代码

  1. 以int类型为例,真正存储数据的是数组,顺序表本身就是基于数组的封装

在这里插入图片描述

  1. 提供构造方法
    在这里插入图片描述

  2. 获取元素个数
    在这里插入图片描述

  3. 自动扩容操作
    在这里插入图片描述

  4. add方法
    在这里插入图片描述
    在这里插入图片描述

  5. get方法
    在这里插入图片描述

  6. remove方法
    在这里插入图片描述
    在这里插入图片描述

  7. toString方法
    在这里插入图片描述

  8. contains方法
    在这里插入图片描述

  9. clear方法
    在这里插入图片描述

  10. indexof方法
    在这里插入图片描述

  11. lastIndexOf方法
    在这里插入图片描述

  12. set方法
    在这里插入图片描述

✏️2.8 ArrayLsit当前面临的问题

1. ArrayList底层使用连续的空间,任意位置插入或删除元素时,需要将该位置后序元素整体往前或者往后搬移,故时间复杂度为O(N)。

2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。

3. 增容一般是呈1.5倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到150,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了45个数据空间。

为了解决以上问题,于是我们引入了链表,可实际上链表真的会解决这些问题吗?还是会带来更多的问题呢?请您继续往下阅读…………

📕3. LinkedList与链表

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

✏️3.1 链表的概念

在这里插入图片描述
实际中链表的结构⾮常多样,以下情况组合起来就有8种链表结构:

  1. 单向或双向
  2. 带头或者不带头
  3. 循环或者非循环

然有这么多的链表的结构,但是我们重点掌握两种:

  1. ⽆头单向⾮循环链表:结构简单,⼀般不会单独⽤来存数据。实际中更多是作为其他数据结构的⼦
    结构,如哈希桶、图的邻接表等等。另外这种结构在笔试⾯试中出现很多。
    在这里插入图片描述

  2. ⽆头双向链表:在Java的集合框架库中LinkedList底层实现就是⽆头双向循环链表。

✏️3.2 LinkedList简介

LinkedList的底层是双向链表结构,由于链表没有将元素存储在连续的空间中,元素存储在单独的节点中,然后通过引⽤将节点连接起来了,因此在在任意位置插⼊或者删除元素时,不需要搬移元素,效率⽐较⾼。

在集合框架中,LinkedList也实现了List接⼝,具体如下:
在这里插入图片描述
注意:

  1. LinkedList实现了List接口
  2. LinkedList的底层使⽤了双向链表
  3. LinkedList的任意位置插⼊和删除元素时效率⽐较⾼,时间复杂度为O(1)
✏️3.3 LinkedList的构造

在这里插入图片描述

✏️3.4 LinkedList常见操作

在这里插入图片描述

✏️3.5 LinkedList常用方法的具体实现代码(重点!!!)

单向链表底层代码实现
双向链表底层代码实现

📕4. ArrayList和LinkedList的区别

在这里插入图片描述

http://www.xdnf.cn/news/14624.html

相关文章:

  • 一步部署APache编译安装脚本
  • 基于SSM框架+mysql实现的监考安排管理系统[含源码+数据库+项目开发技术手册]
  • 使用VIVADO合并FPGA bit文件和Microblaze elf
  • SQL学习笔记2
  • 【大厂机试题解法笔记】可以组成网络的服务器
  • 使用亮数据网页抓取API自动获取Tiktok数据
  • Windows下安装zookeeper
  • 使用OpenCV实现中文字体渲染与特效处理
  • 单片机常用通信外设特点及通信方式对比表
  • 入门级STM32F103C8T6无人机遥控(原理图)
  • window显示驱动开发—支持 DXGI DDI(二)
  • 具身智能新突破:Gemini Robotics On-Device,让机器人拥有“本地大脑”
  • 【智能协同云图库】智能协同云图库第二弹:用户管理系统后端设计与接口开发
  • 开源流媒体平台安装使用
  • C# WinForm跨平台串口通讯实现
  • 2023年全国青少年信息素养大赛Python 复赛真题——玩石头游戏
  • 战地2042(战地风云)因安全启动(Secure Boot)无法启动的解决方案以及其他常见的启动或闪退问题
  • 自然语言处理入门
  • LT8311EX一款适用于笔记本电脑,扩展坞的usb2.0高速运转芯片,成对使用,延伸长度达120米
  • 第五课:大白话教你用K邻近算法做分类和回归
  • 用vscode破解最新typora1.10.8
  • 鸿蒙应用开发中的状态管理:深入解析AppStorage与LocalStorage
  • PYTHON从入门到实践2-环境配置与字符串打印用法
  • 【网络安全】从IP头部看网络通信:IPv4、IPv6与抓包工具 Wireshark 实战
  • vscode + Jlink 一键调试stm32 单片机程序(windows系统版)
  • ArkTS与仓颉开发语言:鸿蒙编程的双子星
  • 软件工程:从理论到实践,构建可靠软件的艺术与科学
  • 【4目方案】基于海思3403平台开发4目360°全景拼接相机方案
  • 五种 IO 模式的简单介绍 -- 阻塞 IO,非阻塞 IO,信号驱动 IO,IO 多路复用,异步 IO
  • RISC-V三级流水线项目:总体概述和取指模块