数据结构与算法分析(三)数组

  1. 为什么数组是从0开始不是从1开始呢
  2. 什么是数组?数组(Array)是一种线性表数据结构。他用一组连续的内存空间,来存储一组具有相同类型的数据
  3. 第一个是线性表(Linear List)线性表就是数据排成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。除了数组,链表、队列、栈等等也是线性表结构
  4. 与线性表对立的概念是非线性表,比如二叉树、堆、图等等。之所以叫非线性,是因为,在非线性表中,数据之间并不是简单的前后关系
  5. 第二个是连续的内存空间和相同类型的数据。正是因为这两个限制,他才有了堪称杀手锏的特性“随机访问”。
  6. 但是这两个限制也让数组的很多操作变得非常低效,比如在数组中删除、插入一个数据,为了保证连续性,就需要做大量的数据搬移工作
  7. 数组是如何实现根据下标随机访问数组元素的????
  8. int[] a = new int [10]  内存块的首地址为base_address=1000 
  9. 计算机会给每个内存单元分配一个地址,计算机通过地址来访问内存中的数据。当计算机需要随机访问数组中的某个元素时,会使用这个寻址公式,计算出该元素存储的内存地址 a[i]_address = base_address + i * data_type_size
  10. data_type_size表示数组中每个元素的大小
  11. 数组和链表的区别:链表适合插入、删除,数组适合查找,数组支持随机访问,根据下标随机访问的时间复杂度为O(1)
  12. 数组中低效的插入操作:假设数组长度为n,把一个数据插入到数组的第k个位置。为了给她腾位置,需要将第k~n的元素顺后挪一位。
  13. 最好的情况在末尾插入,不需要移动其他数据,时间复杂度为O(1)。但如果在数组的开头插入元素,那所有的数据都要往后挪一位,时间复杂度为O(n),随机插入的话平均情况时间复杂度为O(n).
  14. 为了避免大规模数据迁移,可以把第K个位置的元素移到最后,把新的元素直接放入k位置,这样的话时间复杂度O(1)
  15. 数组中的删除操作,跟插入数据类似,如果我们要删除第k个位置的数据,为了内存的连续性,也需要搬移数据,不然中间就会出现空洞,内存就不连续了
  16. 和插入类似,删除末尾元素,则最好情况时间复杂度为O(1),如果删除开头的数据,则最坏情况时间复杂度为O(n);平均情况时间复杂度也为O(n)
  17. 实际上,在某些特殊场景下,我们并不一定非得追求数组中数据的连续性。如果我们将多次删除操作集中在一起执行,删除的效率会提高很多。
  18. 类似于JVM标记清除垃圾回收算法的核心思想
  19. 警惕数组的访问越界问题
  20. 容器能否完全代替数组,针对数组类型,很多语言都提供了容器类,比如java的ArrayList,与数组相比有什么优势呢
  21. ArrayList最大的优势就是可以将很多数组操作的细节封装起来。比如前面提到的数组插入、删除数据时需要搬移其他数据等。并且他支持动态扩容
  22. 数组本身在定义的时候需要预先指定大小,因为需要分配连续的内存空间。如果我们申请了大小为10 的数组,当第11个数据需要存储时会重新分配一块更大的空间,将原来的数据复制过去,再将新的数据插入。
  23. 使用ArrayList,每次存储空间不足都会将空间自动扩容为1.5倍大小,因为扩容操作比较耗时,涉及到内存申请和数据搬移,所以我们可以在创建ArrayList的时候事先指定数据大小
  24. 当然了 数组也有很多适用场景
  • ArrayList无法存储基本类型,比如int,long,需要封装为Integer、Long类,而Autoboxing、Unboxing则由一定的性能消耗,所以如果特别关注性能,或者希望使用基本类型,就可以用数组
  • 如果数据大小已知,并且对数据的操作非常简单,用不到ArrayList提供的大部分方法,也可以直接使用数组
  • 表示多维数组时,用数组往往会更加直观,比如Objectp[][] array;用容器的话:ArrayList<ArrayList> array.
  • 对于业务开发,直接使用容器就足够了。底层开发还是数组,开发网络框架 性能的优化需要做到极致的时候 首选数组

总结:C语言设计者用0开始计数数组下标,之后的Java,JS等高级语言都效仿了C语言,或者说为了减少C语言工程师的学习Java成本,因此而为之。也有些语言,MatLab的数组不是从0开始计算。像Python支持负数下标

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值