java数组思考

92 阅读3分钟

数组是一种数据结构。是内存中的一段连续的内存存储。具有下标。查询的时间复杂度为O1,插入的时间复杂度为On。因为插入的时候,会导致其它元素往后迁移。所以数组适合用来进行频繁的查询。不适合进行频繁的插入删除操作。这些东西,但凡了解过背过的都耳熟能详。

但是,你是否会有一些疑惑呢:

1:为什么数组的查询效率就是O1呢?它不需要去遍历找到对应的下标的那个值,再进行返回吗?

2:为什么数组的插入的效率会是On呢,为啥插入的时候其它数据要进行迁移呢?我直接把对应下标赋值不就好了吗?

华丽分割线________________________

先思考一下上面两个问题… 问题一的答案就是:随机访问,与顺序访问。随机访问就是可以不通过遍历,直接计算出来地址值,从而拿到存放在堆里的值。而顺序访问就是需要通过遍历去找,找到对应的值才能返回。数组就支持随机访问,所以他的查询的时间复杂度是O1。

问题二就比较有问题: 首先,数据为什么要迁移?不迁移不行吗?

数组是定长的。

        比如一个数组里面有54个元素,刚好是一副扑克牌。 
	增加一个元素到55个,这个才叫做插入。
	删除一个元素到54个,这个才叫做删除。

又因为数组是定长的,你这时候,就需要新建一个数组,然后用来存放新的元素数组。 这本身就要走一遍copy的过程。

你比如新增啊。 然后就要考虑新增的元素放的位置: 如果放在最后面,那么还好,前面的元素的下标都不用动,在最后加一个元素就可以了。这就O1的时间。 但是如果放在最前面呢? 那么所有的元素都要往后迁移一位。插入是不是就是On了。 这两种情况都是极端情况。

删除亦如是。

那么怎么样决定放在那里呢?我就不能一直放在最后面吗? 如果是无序的数组,那么就无所谓了,就放在最后面好了。

但是如果是有序的数组。那么就要把新增的元素按照顺序放在指定的位置。那么这个就没办法了。 要根据顺序决定索引的位置。 我又有疑问了: 先不说迁移数据的问题。 拷贝旧的数组,到新的数组中,这个能不耗费性能吗? 毕竟连续内存空间的地址都变了。

这个拷贝是必须的,肯定也耗费性能。然后如果需要排序的话,还需要进行比较。也耗费性能。 但是时间复杂度度为什么还是On呢?

首先,大O符号是用来表示: n与算法的线性关系。忽略常量。
也就是说不考虑开辟空间,拷贝,等时间消耗。

额,所以是On

数组这玩意一般用不到,又不写底层。平时用用list,map就好啦。

也就了解一下。