今天学习了数组:
数组为什么从0开始:
1:因为数组是一块连续的内存空间,其寻址公式为:
a[i]_address=base_address+i*data_type_size(数据类型的字节大小)
如果是从1开始的话,寻址公式为
a[i]_address=base_address+(i-1)*data_type_size
每次随机访问数组元素都多了一次减法运算,对于 CPU 来说,就是多了一次减法指令。从效率的角度从1出发比较好。
历史角度:C 语言设计者用 0 开始计数数组下标,之后的 Java、JavaScript效仿了 C 语言,或者说,为了在一定程度上减少 C 语言程序员学习 Java 的学习成本,因此继续沿用了从 0 开始计数的习惯。
1. 数组如何实现随机访问
1) 数组是一种线性(数组、链表、队列、栈,非线性表:树 图)数据结构,用连续的存储空间存储相同类型数据
因为数组开辟了连续的内存空间而且具有相同的数据,所以数组可以随机访问,但对数组进行删除插入,为了保证数组的连续性,就要做大量的数据搬移工作
a) 数组如何实现下标随机访问。
引入数组再内存种的分配图,得出寻址公式
b) 纠正数组和链表的错误认识。数组的查找操作时间复杂度并不是O(1)。即便是排好的数组,用二分查找,时间复杂度也是O(logn)。
正确表述:数组支持随机访问,根据下标随机访问的时间复杂度为O(1)
2. 低效的插入和删除
1) 插入:从最好O(1) 最坏O(n) 平均O(n)
2) 插入:数组若无序,插入新的元素时,可以将第K个位置元素移动到数组末尾,把心的元素,插入到第k个位置,此处复杂度为O(1)。
3) 删除:从最好O(1) 最坏O(n) 平均O(n)
4) 多次删除集中在一起,提高删除效率
记录下已经被删除的数据,每次的删除操作并不是搬移数据,只是记录数据已经被删除,当数组没有更多的存储空间时,再触发一次真正的删除操作。即JVM标记清除垃圾回收算法。
如果是m*n,二维数组的寻址公式:
a[i][j]== base_address + (i*n+j)* data_type_size。
专栏高手好多,干巴爹!