从单词来看,

Array 很好理解一批一批的意思;

Set 含义比较多,常见有放、集合、一套...;

从字面来记忆它们的区别,Array就是一批一批的,Set是特意放入、采集进去的,所以Array不区分重复,Set区分重复。

下面是是将《秒懂算法:用常识解读数据结构》第一章的内容拷贝来这里,做了一些编辑。

Array work principle

数组示例:

array = ["apples", "bananas", "cucumbers", "dates", "elderberries"]

术语:

  • 大小

    数组大小指的是数组能存放的数据元素的数量。因为上面这个购物清单数组能存储 5 个值,

    所以它的大小是 5。
  • 索引

    数组的索引可以用来标记数据在数组中的位置。

    大部分的编程语言里,索引都是从0开始。

数组的操作:

CURD

速度计量:

衡量操作的速度也被称作衡量其时间复杂度。

不同人会混用速度、时间复杂度、效率、性能以及运行时间这几个术语。一般来说,它们指的都是一个操作所需要的步骤数。

分析Array操作步骤数

read

O(1):常数复杂度,表示无论输入规模如何增长,算法的执行时间都保持不变。

PS:不管有多少数据,读取都是一个步骤。

为什么?

我们在在创建和使用数组的时候,只会关注数组的大小和索引,

但是数组在计算机的底层,它在操作的时候,还需要一个内存地址,下面展示数据、内存地址和索引的关系,

以上的图示,基本就能解释了为什么计算机只用 1 步就能找到数组的第一个值。计算机只要再做一个简单的加法,就能找到任意索引的值。

如果让计算机寻找索引 3 的值,那么它只需在索引 0 的内存地址上加 3 即可。(毕竟内存地址是连续的。)

find

O(n):线性复杂度。表示算法的执行时间与输入规模成线性关系。

还是以之前的数组为例。计算机无法立刻弄清每个格子的内容。对计算机来说,

这个数组看起来就像下面示例这样。

【?,?,?,?,?】

比如说需要它去找dates这个数据,那么就步骤如下,

会第0索引开始找dates这个数据,

  1. 第一次,没找到:

    【apples,?,?,?,?】
  2. 第二次,没找到:

    【apples,bananas,?,?,?】
  3. 第三次,没找到:

    【apples,bananas,cucumbers,?,?】
  4. 第四次,找到:

    【apples,bananas,cucumbers,dates,?】
  5. 退出

insert

需要明白的是在Array里,插入到数组的最后一列,和从中间插入是两种不同的操作。

最后一列插入

一旦计算机算出了存储新值的内存地址,它只需要 1 步就能完成插入。

下图展示了在数组末尾插入"figs"的过程。

so, O(1):常数复杂度,表示无论输入规模如何增长,算法的执行时间都保持不变。

中间插入

假设我们要在索引 2 处插入"figs"。先来看下图,

为此,需要向右移动"cucumbers"、"dates"和 "elderberries"来给"figs"腾出空间。这

个过程需要多步,因为需要先把"elderberries"向右移动一个格子,才能移动"dates"。然后,

再移动"dates"来给"cucumbers"让位。

在这个例子中,插入需要 4 步,其中 3 步是数据右移,剩下 1 步是插入新值。

向数组开头插入元素需要步数最多,也就是所谓的最坏情况。 这是因为要在数组开头插入元

素,必须把其他所有值都右移一个格子。

对包含 N 个元素的数组来说,最坏的情况下需要 N + 1 步插入。这是因为需要移动 N 个元

素,然后才能执行插入操作。

so, O(n+1):线性复杂度。表示算法的执行时间与输入规模成线性关系。

delete

删除指的是删去特定索引的值的过程。

下面以删除购物清单数组索引 2 处的值为例。在这个数组中,这个值是"cucumbers"。

严格意义上来说,删除"cucumbers"只需 1 步。但有一个问题:数组中间有了一个空格子。

中间有空格子的数组是无效的。

要解决这个问题,需要把"dates"和"elderberries"左移。因此删除操作还需要额外步骤。

这个删除操作用了 3 步。1 步是删除元素,另外 2 步是移动元素来填补空格子。

和插入一样,删除元素的最坏情况是删除数组中的第一个元素。因为索引 0 会变成空格子,

所以必须把剩余的所有元素都左移。

so, O(n+1):线性复杂度。表示算法的执行时间与输入规模成线性关系。

Set work principle

why is Set ?

集合的定义是,集合中包含的元素不能重复。

集合有多种类型,但本节只讨论基于数组的集合。这种集合和数组很相似,它们都是存储值

的简单列表,二者的唯一区别在于,不能往集合中插入重复的值。

假设已知集合["a", "b", "c"],而你想再添加一个"b"。因为"b"已经存在于集合中,所以计算机会拒绝这次操作。

当需要确保数据不重复时,集合非常有用。

Set的操作:

CURD

分析Set操作步骤数

read

集合的读取和数组的读取完全一致,即计算机检查特定索引处的值只需要 1 步。这是因为计

算机能跳转到集合内的任意索引,而这只需简单地计算并跳转到其内存地址即可。

find

集合的查找也和数组的查找没什么区别,即查找集合中的值最多需要 N 步。集合和数组的

删除操作也一模一样,即要删除一个值并移动其他数据来填空最多需要 N 步。

insert

集合的插入和数组的插入则不同。先来看看在集合末尾插入值。这对数组来说只需要 1 步,

是最好的情况。

但集合不同,计算机需要先判断这个值是否存在于集合中——因为集合的规则是不允许插入

重复数据。

计算机要如何确保新数据不在集合中呢?

  • 计算机一开始并不知道数组或者集合的格子中都存储了什么值。

  • 因此,它必须先在集合中查找,才能知道要插入的值是否已经存在。只有集合中不存在这个新值的时候,计算机才能继续执行插入操作。(所以,所有的插入操作都需要先进行查找。)

来看一个例子。假设之前提到的购物清单是用集合存储的。这个假设很合理,因为我们不想

重复购物。假设集合目前是["apples", "bananas", "cucumbers", "dates", "elderberries"],

而我们想插入"figs"。

计算机必须执行以查找"figs"为首的如下操作:



"figs"不在索引 0 处,但可能在集合中的其他位置。在插入之前,需要确保"figs"也不在

这些位置。

查找过整个集合后,我们确定其中没有"figs"。这时,就可以完成插入操作了。所以最后

一步如下。

第 6 步:在集合末尾插入"figs"。

最后插入

在集合末尾插入值是最好的情况,但对含有 5 个元素的集合来说仍然需要 6 步。换言之,必

须查找其全部 5 个元素之后才能执行插入操作。

换种说法:对包含 N 个元素的集合来说,在集合末尾插入值最多需要 N + 1 步。这是因为确

定集合中不含该值需要 N 步,而实际的插入还需要 1 步。数组的相同操作则只需要 1 步。

so, O(n+1):线性复杂度。表示算法的执行时间与输入规模成线性关系。

中间插入

向集合开头插入值是最坏的情况。为此,计算机需要先查找 N 个格子来确保该值不在集合

中,然后再用 N 步来右移全部数据,最后再用 1 步来插入新值。全部加起来是 2N + 1 步。

数组的相同操作则只需要 N + 1 步。

so, O(2n+1):线性复杂度。表示算法的执行时间与输入规模成线性关系。

delete

集合和数组的删除操作也一模一样,即要删除一个值并移动其他数据来填空最多需要 N 步。

Java Collection Class

在Java中,想使用array和set,需要了解Collection,

Collection
|------List
| |------ArrayList
| |------LinkedList
| |------Vector
| |------Stack
|
|------Set
|------HashSet
| |------LinkedHashSet
|
|------SortedSet
|------TreeSet
|------NavigableSet |------Queue
|------Deque
| |------ArrayDeque
| |------LinkedList |------Map
|------HashMap
| |------LinkedHashMap
|
|------SortedMap
|------TreeMap
|------NavigableMap

如果从粗略的来看,

array 就是 ArrayList,

set 就是 TreeSet。

Array and Set work process的更多相关文章

  1. python学习笔记——多进程中共享内存Value & Array

    1 共享内存 基本特点: (1)共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝. (2)为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将 ...

  2. 多进程Process

    多进程旧式写法 from multiprocessing import Pool def f(x): return x*x if __name__ == '__main__': p = Pool(5) ...

  3. Disk array controller and information processing apparatus

    A disk array controller has a function of relocating a plurality of data blocks stored in a disk arr ...

  4. Java进程Runtime、Process、ProcessBuilder调用外部程序

    原文地址:https://blog.csdn.net/c315838651/article/details/72085739 通过Java执行系统命令,与cmd中或者终端上一样执行shell命令,最典 ...

  5. Python网络编程之线程,进程

    一. 线程: 基本使用 线程锁 线程池 队列(生产者消费者模型) 二. 进程:  基本使用  进程锁 进程池 进程数据共享 三. 协程: gevent greenlet 四. 缓存: memcache ...

  6. python——进程基础

    我们现在都知道python的多线程是个坑了,那么多进程在这个时候就变得很必要了.多进程实现了多CPU的利用,效率简直棒棒哒~~~ 拥有一个多进程程序: #!/usr/bin/env python #- ...

  7. 循序渐进Python3(八) -- 1 -- socket进阶

    IO多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. Linux中的 select,poll,epoll 都 ...

  8. Python学习之路--进程,线程,协程

    进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Q ...

  9. python任务执行之线程,进程,与协程

    一.线程 线程为程序中执行任务的最小单元,由Threading模块提供了相关操作,线程适合于IO操作密集的情况下使用 #!/usr/bin/env python # -*- coding:utf-8 ...

  10. python成长之路 :线程、进程和协程

    python线程 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分 ...

随机推荐

  1. 图书管理系统---基于ajax删除数据

    book_list.html代码 {% load static %} <!DOCTYPE html> <html lang="en"> <head&g ...

  2. 【LeetCode排序专题01】由旋转数组的最小数字引出的关于排序算法的讨论(冒泡排序、二分查找+暴力法)

    旋转数组的最小数字 剑指 Offer 11. 旋转数组的最小数字 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 给你一个可能存在 重复 元素值的数组 numbers ,它原来是一 ...

  3. IISExpress 跨域cookie的奇怪问题

    测试环境 WIN10,IIS 10,IISExpress 10,Chrome 120,Microsoft Edge 114 网站A 端口7001 只有1个Default.aspx,无前端代码.逻辑很简 ...

  4. 出海业务如何搭建国内也能快速访问的https网站与接口(无需备案)

    背景信息 由于最近在搭建我的出海网站 https://www.idatariver.com/zh-cn , 感兴趣的可以看看. 其中一个环节便是给后端API接口加上ssl,毕竟http看着不如http ...

  5. vue3使用路由keep-alive和监听路由实现transition

    随着vue3.0的发布,vue-router发布了4.0版本,文档 很明了,提供了vue2路由到vue3的变化和写法指导. vue2: // transition <transition nam ...

  6. JS5-PC端网页特效

    常见offset系列属性作用 常见client系列属性作用 常见scroll系列属性作用 封装简单动画函数 写出网页轮播图案例 offset 偏移量,使用offset相关属性可以动态的得到该元素的位置 ...

  7. Zabbix“专家坐诊”第192期问答汇总

    问题一 Q:请问下,客户机snmptrap发告警为啥server web收不到,关键是snmptrap日志已经收到,zabbix server配置以及开启snmptrap=1 snmptrap=var ...

  8. C++ explicit 关键字简介

    explicit 关键字修饰构造函数 防止类的初始化的时候进行隐式转换. class MyClass { string m_s; int m_a, m_b; public: MyClass(strin ...

  9. dubbo 泛化调用场景下,如何调用下游的泛型对象入参

    dubbo泛化调用时,除了java原生的collection,map泛型对象,业务自定义的泛型对象是不支持泛化调用的,无法正确的填充下游数据对象.两种解法: 泛化调用的时候把泛型具体类型的全限定类路径 ...

  10. API和String字符串介绍

    API 1.如何使用Java已经写好的东西(方法,类) API(Application programming interface):应用程序编程接口 简单理解:API就是别人已经写好了的东西,我们不 ...