05:数组
2021-04-02 06:26
标签:log cpu type 16px 运算 ext size 核心 结构 在大部分编程语言中,数组都是从0开始编号的,为什么数组要从0开始编号,而不是从1开始呢? 数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。 线性表:数组、链表、栈、队列 非线性表:二叉树、堆、图等 在非线性表中,数据之间并不是简单的前后关系 如何实现随机访问?==》线性表;连续的内存空间和相同类型的数据 根据下标随机访问数组元素==》a[i]_address = base_address + i * data_type_size data_type_size表示数组中每个元素的大小 数组查找的时间复杂度==》二分查找:O(logn) 数组支持随机访问,根据下标随机访问的时间复杂度为O(1) 低效的“插入”和“删除”==》数组为了保持内存数据的连续性,会导致插入、删除这两个操作比较低效 ============================================================= 如果在数组的末尾插入元素,就不需要移动数据了,这时的时间复杂度为 O(1)。 如果在数组的开头插入元素,那所有的数据都需要依次往后移动一位,所以最坏时间复杂度是 O(n)。 因为在每个位置插入元素的概率是一样的,所以平均情况时间复杂度为 (1+2+…n)/n=O(n)。 ============================================================= 改进:如果数组中的数据是有序的,在某个位置插入一个新的元素时,就必须按照刚才的方法搬移 k 之后的数据。 但是,如果数组中存储的数据并没有任何规律,数组只是被当作一个存储数据的集合。在这种情况下,如果要将某个数据插入到第 k 个位置,为了避免大规模的数据搬移,还有一个简单的办法就是,直接将第 k 位的数据搬移到数组元素的最后,把新的元素直接放入第 k 个位置。 删除 ============================================================ 要删除第 k 个位置的数据,为了内存的连续性,也需要搬移数据,不然中间就会出现空洞,内存就不连续了。 和插入类似,如果删除数组末尾的数据,则最好情况时间复杂度为 O(1);如果删除开头的数据,则最坏情况时间复杂度为 O(n);平均情况时间复杂度也为 O(n)。 在某些特殊场景下,并不一定非得追求数组中数据的连续性。如果将多次删除操作集中在一起执行,删除的效率会提高很多 先记录下已经删除的数据。每次的删除操作并不是真正地搬移数据,只是记录数据已经被删除。当数组没有更多空间存储数据时,再触发执行一次真正的删除操作,这样就大大减少了删除操作导致的数据搬移。 JVM标记-清除垃圾回收算法的核心思想 ========================================================== 数组越界:java.lang.ArrayIndexOutOfBoundsException 容器: ArrayList 最大的优势就是可以将很多数组操作的细节封装起来。比如数组插入、删除数据时需要搬移其他数据等。 另外,它还有一个优势,就是支持动态扩容。数组本身在定义的时候需要预先指定大小,因为需要分配连续的内存空间。如果我们申请了大小为 10 的数组,当第 11 个数据需要存储到数组中时,我们就需要重新分配一块更大的空间,将原来的数据复制过去,然后再将新的数据插入。如果使用 ArrayList,我们就完全不需要关心底层的扩容逻辑,ArrayList 已经帮我们实现好了。每次存储空间不够的时候,它都会将空间自动扩容为 1.5 倍大小。因为扩容操作涉及内存申请和数据搬移,是比较耗时的。所以,如果事先能确定需要存储的数据大小,最好在创建 ArrayList 的时候事先指定数据大小。 ========================================================== 从数组存储的内存模型上来看,“下标”最确切的定义应该是“偏移(offset)” 如果用 a 来表示数组的首地址,a[0]就是偏移为 0 的位置,也就是首地址,a[k]就表示偏移 k 个 type_size 的位置,所以计算 a[k]的内存地址只需要用这个公式:a[k]_address = base_address + k * type_size 但是,如果数组从 1 开始计数,那我们计算数组元素 a[k]的内存地址就会变为:a[k]_address = base_address + (k-1)*type_size 从 1 开始编号,每次随机访问数组元素都多了一次减法运算,对于 CPU 来说,就是多了一次减法指令。 二维数组内存寻址: 05:数组 标签:log cpu type 16px 运算 ext size 核心 结构 原文地址:https://www.cnblogs.com/liushoudong/p/13507492.html
对于 m * n 的数组,a [ i ][ j ] (i
address = base_address + ( i * n + j) * type_size
下一篇:c++设计模式概述之状态