美文网首页
深入浅出数组底层

深入浅出数组底层

作者: LeeYaMaster | 来源:发表于2019-05-16 21:25 被阅读0次

我们在用数组的时候,直接定义一个数组,根据下标删除,或者根据下标增加,又或者遍历,这些都是最基本的操作,但是呢?你有没有考虑过数组是怎么实现的,以及怎样使用数组效率最高,还有数组下标为什么从0开始呢?这便是我们探讨的问题:

数组是什么?

如果学过数据结构(这个对了解底层非常重要!),就知道,他是一个线性表数据结构,与之,链表,队列,栈也是。还有一种数据结构为非线性表,例如图,堆,二叉树。区别就在于线性表中,有前后关系:


原谅我用下墨刀画图

数组占了多少内存?

我们定义一个长度为10的int类型的数组int[] a = newint[10]来举一个热腾腾的栗子,分配了一块连续内存空间1000~1039,因为int,是最基本的类型,默认是4个字节,一般和CPU的字宽一致,为了提高CPU的处理速度。
其中,计算机会给每个内存单元分配一个地址,计算机可以通过地址来访问内存中的数据。当计
算机需要访问数组中的某个元素时,它会首先通过下面的寻址公式,计算出该元素存储的内
存地址,内存块的首地址为base_address = 1000,

a[i]_address = base_address + i * data_type_size//内存寻址公式,寻址公式有7种
数据类型,字节大小表

如上,我们定义了10个int类型的变量,所以是40字节,内存占用1000~1039正确。不同的数据类型占用不同的内存。

插入和删除,怎样避免消耗性能?

我们定义一个数组(用的JS写法):

  var arr=[1,2,3,4,5];

往数组末尾添加元素,发现并没什么性能上的问题。

arr.push(6);

但是往数组中间放元素就不一样了:

arr.splice(2,0,5);//在下标2处,添加一个5元素,最后输出为[1,2,5,3,4,5];

为什么会不一样呢?就是因为性能的元素,往中间插入元素,后面的元素,会往后移一位,这对性能消耗是非常大的,如果在最后插入元素,那么不用挪位,时间复杂度为O(1),如果在最前面,时间复杂度为O(n),那么平均复杂度则为O(n)。
有没有什么方法可以不那么消耗性能?当然是有,我们可以把要添加的元素位置,进行替换,然后再把被替换的,放到数组最后面去,这样也可以完成操作,在快速排序算法中,就是用的这种思想。

arr.push(arr[3]);
arr[3]=5;

这样就完成啦。至于删除,大同小异,不过删除这操作,为了避免数组的元素挪动,以及多次删除,可以将多次删除,整合到一起删,这样效率就会提高了。还有一种是我想出来的方法,把要删除的元素,设置成undefined(JS),然后通过for in循环,就可以删除undefined的数据啦。
PS:Java底层虚拟机JVM标记清除垃圾回收算法的核心思想也是这个,数据结构是底层的东西,学好了这个,学其他高级语言,都非常容易。

数组为什么是从0开始:

首先,定义就是这样子定义的,1+1=2,人就是这样定义,这些东西是证明不了的,arr[0]这里的0是指的偏移量。

a[i]_address = base_address + i * data_type_size

套用上面的寻址公式,就这么简单。(当然,有些例外,Python下标可以从负数开始,MatLab下标不是从0计数等等)

相关文章

  • 深入浅出数组底层

    我们在用数组的时候,直接定义一个数组,根据下标删除,或者根据下标增加,又或者遍历,这些都是最基本的操作,但是呢?你...

  • JDK1.8关于HashMap的变化

    底层实现原理 ++1.7++HashMap底层是使用数组+链表实现 ++1.8++HashMap底层是使用数组+链...

  • Scala学习笔记03_数组

    Array Array,长度不可改变的数组,Scala数组的底层实际上是Java数组,如字符串数组在底层就是Jav...

  • go基础编程day4切片slice与map

    切片slice 本身并不是数组,它指向底层的数组 作为变长数组的替代方案,可以关联底层数组的局部或者全部 为引用类...

  • 《日子》golang-切片slice

    切片Slice -其本身并不是数组,它指向底层的数组-作为变长数组的替代方案,可以关联底层数组的局部或全部-为引用...

  • ArrayList和LinkedList的区别

    1.底层实现层面: ArrayList底层是由数组实现,是一个动态数组,而LinkedList底层是一个双向链表。...

  • golang - slice

    切片定义 切片是基于数组实现的,它的底层是数组,可以理解为对 底层数组的抽象。切片底层结构并没有使用加锁等方式,不...

  • 七.Go切片slice

    切片slice 本身并不是数组,它指向底层的数组 作为变长数组的替代方案,可关联底层数组的局部或全部 数据类型为引...

  • go编程基础-切片

    切片-slice 1.其本身并不是数组,它指向底层的数组,作为变长数组的替代方案,可以关联底层数组的局部和全部为引...

  • 07 切片slice

    其本身并不是数组,它指向底层的数组作为变长数组的替代方案,可以关联底层数组的局部或全部为引用类型可以直接创建或从底...

网友评论

      本文标题:深入浅出数组底层

      本文链接:https://www.haomeiwen.com/subject/rulwaqtx.html