数组看似简单,但掌握精髓的却没有多少;他既是编程语言中的数据类型,又是最基础的数据结构;html
一个小问题:算法
为何数据要从0开始编号,而不是 从1开始呢?编程
带着问题进入学习数组
数组(array)是一种线性表数据结构,它用一组连续的内存空间来储存一组具备相同类型的数据。数据结构
咱们从定义来分析:框架
线性表:编程语言
是数据排成像一条线同样的结构。每一个线性表上的数据最多有先后两个方向。诸如数组,链表,队列,栈等都是线性表结构。性能
连续的内存空间和相同类型的数据:学习
这个特性是数组“随机访问”速度飞快的原因,这也致使了从数组中删除、插入数据,为了保证连续性,须要大量的工做量spa
计算机会给每一个内存单元分配一个地址,计算机经过地址来访问内存中的数据。
当计算机随机访问数组中的某个元素时,它会首先经过下面的寻址公式,计算出该元素的内存地址:
a[i]_address = base_address + i * data_type_size
data_type_siza表示数组中的每个元素的大小。若是是int类型的数据,data_type_size为4个字节;
链表适合插入、删除,时间复杂度为O(1),数组适合查找,可是这里要注意一下,时间复杂度并非O(1),即使是排好序的数组,你用二分法查找,时间复杂度也是O(logn),
正确的描述为:数组支持随机访问,根据下标随机访问的时间复杂度为O(1)
假设数组的长度为 n,如今,若是咱们须要将一个数据插入到数组中的第 k 个位置,为了把第 k 个位置腾出来,给新来的数据,咱们须要将第 k~n 这部分的元素都顺序地日后挪一位,下面咱们分析一下时间复杂度
若是在数组的末尾插入元素,那就不须要移动数据了,这时的时间复杂度为 O(1),但若是在数组的开头插入元素,那全部的数据都须要依次日后移动一位,因此最坏时间复杂度是 O(n),由于咱们在每一个位置插入元素的几率是同样的,因此平均状况时间复杂度为 (1+2+…n)/n=O(n)
若是数组中的数据是有序的,咱们在某个位置插入一个新的元素时,就必须按照刚才的方法搬移 k 以后的数据,若是数组中存储的数据并无任何规律,数组只是被看成一个存储数据的集合。在这种状况下,若是要将某个数组插入到第 k 个位置
为了不大规模的数据搬移,咱们还有一个简单的办法就是
直接将第 k 位的数据搬移到数组元素的最后,把新的元素直接放入第 k 个位置。
和插入相似,
若是删除数组末尾的数据,最好状况时间复杂度为 O(1);
若是删除开头的数据,则最坏状况时间复杂度为 O(n);
平均状况时间复杂度也为 O(n)
将屡次删除操做中集中在一块儿执行,能够先记录已经删除的数据,可是不进行数据迁移,而仅仅是记录,当发现没有更多空间存储时,再执行真正的删除操做。这也是 JVM 标记清除垃圾回收算法的核心思想。
C语言中的数据越界是一种未决行为,通常比较难发现的逻辑错误。相比之下,Java会有越界检查。
数组先指定了空间大小,容器如ArrayList能够动态扩容。
1.但愿存储基本类型数据,能够用数组
2.事先知道数据大小,而且操做简单,能够用数组
3.直观表示多维,能够用数组
4.业务开发,使用容器足够,开发框架,追求性能,首先数组。
因为数组是经过寻址公式,计算出该元素存储的内存地址:
a[i]_address = base_address + i * data_type_size
若是数组是从 1 开始计数,那么就会变成:
a[i]_address = base_address + (i-1)* data_type_size
以上内容为我的的学习笔记,仅做为学习交流之用。
欢迎你们关注公众号,不定时干货,只作有价值的输出
做者:Dawnzhang
出处:http://www.javashuo.com/article/p-mrqlqxsk-gh.html
版权:本文版权归做者转载:欢迎转载,但未经做者赞成,必须保留此段声明;必须在文章中给出原文链接;不然必究法律责任