算法基础-数组

萝らか妹 提交于 2019-12-08 15:17:18

收获点滴:

1.数组的查询效率比链表高?

答:哪怕排好序的数组,利用二分法查询时间复杂度也是 O(logn)。所以,正确的表述应该是,数组支持随机访问,根据下标随机访问的时间复杂度为 O(1)。

2.数组插入和删除的效率低?

答:对于实际上,在某些特殊场景下,我们并不一定非得追求数组中数据的连续性。如果我们将多次删除操作集中在一起执行,删除的效率是不是会提高很多呢?,如果数组只是存储数据的容器,存储的数据没有任何规律,这时需要把某个数插入到第K个位置,这时为了避免大规模数据移动,把第K个数移到数组末尾,在把新元素放置到K位置。
在这里插入图片描述
对于删除操作,实际上,在某些特殊场景下,我们并不一定非得追求数组中数据的连续性。如果我们将多次删除操作集中在一起执行,删除的效率是不是会提高很多呢?
我们继续来看例子。数组 a[10] 中存储了 8 个元素:a,b,c,d,e,f,g,h。现在,我们要依次删除 a,b,c 三个元素。
在这里插入图片描述
为了避免 d,e,f,g,h 这几个数据会被搬移三次,我们可以先记录下已经删除的数据。每次的删除操作并不是真正地搬移数据,只是记录数据已经被删除。当数组没有更多空间存储数据时,我们再触发执行一次真正的删除操作,这样就大大减少了删除操作导致的数据搬移。

3.容器能否完全替代数组?

1.Java ArrayList 无法存储基本类型,比如 int、long,需要封装为 Integer、Long 类,而 Autoboxing、Unboxing 则有一定的性能消耗,所以如果特别关注性能,或者希望使用基本类型,就可以选用数组。
2. 如果数据大小事先已知,并且对数据的操作非常简单,用不到 ArrayList 提供的大部分方法,也可以直接使用数组。
3. 还有一个是我个人的喜好,当要表示多维数组时,用数组往往会更加直观。比如 Object[][] array;而用容器的话则需要这样定义:ArrayList > array。我总结一下,对于业务开发,直接使用容器就足够了,省时省力。毕竟损耗一丢丢性能,完全不会影响到系统整体的性能。但如果你是做一些非常底层的开发,比如开发网络框架,性能的优化需要做到极致,这个时候数组就会优于容器,成为首选。

4.为什么数组要从0开始编号?

因为数组的首地址是数组第1个元素存储空间的起始位置,若用下标0标记第1元素则通过寻址公式计算地址时直接使用下标值计算,即a[0]_address = base_address + 0 * data_type_size。若用下标1标记第1个元素则通过寻址公式计算地址时需将下标值减1再计算,即a[1]_address = base_address + (1-1) * data_type_size,这样每次寻址计算都多了一步减法操作,增加了性能开销。不过也有可能是历史原因,因为之前C语言就是0开始的,Java为了减少学习成本,所以继续沿用从0开始计数的习惯。

5.Java的二维数组地址是连续的么?

二维数组A:
int [][] A = { { 1, 0, 12, -1 },
{ 7, -3, 2, 5 },
{ -5, -2, 2, -9 }
};
内存结构如图:
在这里插入图片描述
参考:http://math.hws.edu/javanotes/c7/s5.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!