1.前言:

我们提到程序中的集合的时候,往往脑海中会浮现出, 如ArrayList和LinkedList以及和HashMap。当然在提到ArrayList和LinkedList的时候,我们大多数的人都知道一点:ArrayList查询速度快,操作速度慢。LinkedList查询速度慢,但是操作速度快。但是why ? 为什么会是这样的现象? 那么接下我从数据结构角度带大家一起去认识下这个问题。

2.数据结构 --- 线性表

数据结构是计算机存储、组织数据的方式。

数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。

上述概念得出:数据结构 = 数据存储 + 数据集合。

线性表: 线性表是一个线性结构,它是一个含有n≥0个结点的有限序列,对于其中的结点,有且仅有一个开始结点没有前驱但有一个后继结点,有且仅有一个终端结点没有后继但有一个前驱结点,其它的结点都有且仅有一个前驱和一个后继结点。

在数学的角度 线程表A = { A0, A1, A2, ….. , An-1, An, An+1 } ,那么我们称之为 An-1 是 An 的前驱元 ,An+1 是后继元。

3.存储方式

我们简单的认识了线性表的结构 ,那么根据计算机存储不同, 我们将线性表分类成为:线性存储和链式存储。

3.1 线性存储

线性表中线性储存表示我们数据结构在中的元素在存储元素的时候是按照顺序在计算机内存中存储。 典型代表:ArrayList

线性存储的设计数据结构需要包含以下:

I. 起始位置

II. 数组

III. 表空间元素存储位置

从上面我们可以看的出来,我们在设计线程表的时候是通过数组的形式来维护的数据结构的关系,不需要我们自行设计逻辑关系的维护。

数组在维护逻辑关系上来说,由于数组本身包含记录着元素索引。索引搜索起来的速度较快。

缺点:

由于是由数组维护数据结构,会产生一些问题?

第一. 在实现元素的添加的时候,涉及的一个问题就是数组的自动扩容策略。

顺序存储的线性链表在选择自动扩容的测试就是数组的拷贝。

参考ArrayList;源码分析 元素添加方法

其中自动扩容选择了Arrays.copyOf(elementData, newCapacity) 数组的拷贝实现。

那么数组在拷贝的时候,就是涉及到 数据结构中的元素的大量的拷贝迁移

从图一到图二的过度,是我们线性表的自动扩容的过程,涉及到的步骤有数组的新建和元素的拷贝,这样就额外的增加了性能开销。

第二. 空间碎片问题

我们在使用数组开辟内存空间, 但是当我们并没有使用完数组的开辟的空间时候,那么剩余未被使用的空间就会被一直占用不能被释放出来,造成了空间的浪费,这称之为空间碎片

3.2 链式存储

线性表中链式存储存表示我们数据结构在中的元素在存储元素的时候是随机存放在计算机内存中可用的区域存储。这样可以更好的利用内存空间 。典型代表LinkedList

链式存储的线性表结构:设计时不使用数组来维护元素的逻辑关系,需要我们设计节点来描述数据结构中的元素关系。

节点之间需要我们去维护 “ 邻居关系”, 使用任意一组存储单元存储元素,线性表之间的线性逻辑关系是通过这组存储单元中的指针域去指向下一组存储单元,下一组储存单元可以放在任意位置。

参考LinkedList源码:

那么通过上面的数据结构我们可以看出,链式存储的线性表的逻辑关系是通过指针域存储逻辑关系,所以内存上的分布是逻辑上的关联,而物理上是分离的。

这样设计的好处在于,提升了内存的使用效率,避免了空间碎片问题。逻辑关系可以自行维护。那么在实现添加或者删除逻辑操作会更加高效。

今天主要带领大家从数据结构的视角认识我们的简单表结构。 学会了吗? 不一样的角度认识我们的老朋友 ArrayList和LinkedList。接下来还有更多java后端相关知识奉上,请多多关注上海尚学堂JAVA培训,期待下次见面。

站在JAVA数据结构的视角看待简单表结构的更多相关文章

  1. Java数据结构和算法 - 哈希表

    Q: 如何快速地存取员工的信息? A: 假设现在要写一个程序,存取一个公司的员工记录,这个小公司大约有1000个员工,每个员工记录需要1024个字节的存储空间,因此整个数据库的大小约为1MB.一般的计 ...

  2. 自己动手实现java数据结构(九) 跳表

    1. 跳表介绍 在之前关于数据结构的博客中已经介绍过两种最基础的数据结构:基于连续内存空间的向量(线性表)和基于链式节点结构的链表. 有序的向量可以通过二分查找以logn对数复杂度完成随机查找,但由于 ...

  3. 【Java数据结构与算法】简单排序、二分查找和异或运算

    简单排序 选择排序 概念 首先,找到数组中最小的那个元素,其次,把它和数组的第一个元素交换位置(如果第一个元素就是最小的元素那么它就和自己交换).再次,在剩下的元素中找到最小的元素,将它与数组的第二个 ...

  4. Java数据结构——树的三种存储结构

    (转自http://blog.csdn.net/x1247600186/article/details/24670775) 说到存储结构,我们就会想到常用的两种存储方式:顺序存储和链式存储两种. 先来 ...

  5. Java数据结构与算法(1):线性表

    线性表是一种简单的数据类型,它是具有相同类型的n个数据元素组成的有限序列.形如如A0,A1,...,An-1.大小为0的表为空表,称Ai后继Ai-1,并称Ai-1前驱Ai. printList打印出表 ...

  6. 一文掌握关于Java数据结构所有知识点(欢迎一起完善)

    在我们学习Java的时候,很多人会面临我不知道继续学什么或者面试会问什么的尴尬情况(我本人之前就很迷茫).所以,我决定通过这个开源平台来帮助一些有需要的人,通过下面的内容,你会掌握系统的Java学习以 ...

  7. Java数据结构之队列的实现以及队列的应用之----简单生产者消费者应用

    Java数据结构之---Queue队列 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在 ...

  8. Java数据结构和算法 - 简单排序

    Q: 冒泡排序? A: 1) 比较相邻的元素.如果第一个比第二个大,就交换它们两个; 2) 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数; 3) 针 ...

  9. 数据结构笔记--栈的总结及java数组实现简单栈结构

    杂谈"栈"结构: 栈(Stack)是一种插入删除操作都只能在一个位置上进表,这个位置位于表的末端,叫做栈顶(Top). 对栈的基本操作有push和pop,表示进栈和出栈.也就相当于 ...

随机推荐

  1. php 积分抽奖活动(大转盘)

    以下是项目代码(公众号,使用积分进行抽奖活动),只可做参考: public function Sncode(){ $tid = I('request.tid', 0, 'intval'); // 大转 ...

  2. hibernate的理解

    emm~这里就是记录一下,hibernate的save,如果存在id,就可以直接save,就会覆盖原有的,如果不存在id就会在数据库创建一条新的记录 package edu.zut.cs.zutnlp ...

  3. Android面试准备20190422

    1.即时推送原理,采用的push推送模式,保持一个长连接,服务端和客户端连接后不再断开.所谓长连接,即是在一个TCP上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发送检测 ...

  4. Git那些事儿

    Git是目前世界上最先进的分布式版本控制系统,适合多人协作开发的大型项目.我平常也经常使用git,来管理自己的几个小项目.简单说说git的原理和git的特点!(只有知道了一个工具的运行原理,设计思路, ...

  5. 怎么清理Linux系统磁盘空间占用大:/dev/xvda1

    1.首先查看磁盘占用情况 df -h Filesystem      Size  Used Avail Use% Mounted on/dev/xvda1       20G   18G  621M  ...

  6. VSCode的使用

    前后端分离的,先打开vs,打开你的项目,在项目根目录中找到.vs文件加,找到.vs\config\applicationhost.config,然后打开找到你项目的IIS Express配置,例如:& ...

  7. Linux使用yum安装JDK

    安装jdk8 检查系统是否自带open-jdk输入命令: #rpm -qa|grep java #rpm -qa|grep jdk 如果没有输入信息表示没有安装,如果安装可以输入命令:#rpm -qa ...

  8. iOS.ObjC.__attribute__-directives

    __attribute__ Directives Reference 1. __attribute__ directives in Objective-C (AAAA+) (Read Again) h ...

  9. python基础 (初识函数&函数进阶)

    函数基础部分 .什么是函数? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率. 2.定义函数 定义:def 关键词开头,空格之后接函数名 ...

  10. Python语言学习之C++调用python

    C++调用python 在C/C++中嵌入Python,可以使用Python提供的强大功能,通过嵌入Python可以替代动态链接库形式的接口,这样可以方便地根据需要修改脚本代码,而不用重新编译链接二进 ...