数据结构---数组

  1. 数组是一种线性表结构,可以用一组连续的内存空间,来存储一组具有相同类型的数据。
    1. 关于线性表:就是数据排成像一条线一样的结构,线性表上的数据方向只有向前和向后。数组、链表、队列和栈都是线性表。非线性表:就是数据之间不是简单的前后关系。比如二叉树、堆和图。
    2. 关于连续的内存空间:计算机在分配内存空间的时候都会对应分配一个内存地址,连续的内存空间对应着连续的内存地址,计算机通过访问内存地址获取内存中的值。
    3. 关于相同类型的数据:就是数据存储所占用的内存大小是一样的。
    4. 随机访问:在存取第N个数据时,不需要访问前(N-1)个数据,就可直接对第N个数据进行操作。非随机访问:在存取第N个数据时,必须先访问第(N-1)个数据。因为数组有着连续的内存空间和存储着相同类型的数据,因此,数组支持随机访问。而链表则不支持随机访问。对随机访问的寻址公式是a[n]_address=base_address+n*data_type_size.其中,data_type_size指每个元素的大小,比如int类型的,data_type_size为4个字节。base_address为首地址。常见的数据类型如下表所示。
      数据类型data_type_size
      int4
      char1
      double8
      float4
      short2
      long4
    5. 纠正一个错误说法:常常问链表和数组的区别时,很多人回答说:“链表适合插入和删除操作,时间复杂度为O(1);数组适合查找操作,时间复杂度为O(1)。这种描述是不准确的。因为数组虽然适合查找,但是时间复杂度不是O(1),即使是排好序的数组,用二分查找,其时间复杂度也只是O(logn)。所以正确的描述应为:”数组支持随机访问,根据下标进行随机访问的时间复杂度为O(1)“。

  2. 为什么数组的“插入、删除”操作很低效?
    1. 对于插入操作而言:在长度为n的数组的第k个位置插入一个数据时,为了保持线性结构,需要将第k个位置空出来,而相应的第k~n个数据需要向后腾挪一位。这样操作的最好时间复杂度为O(1),最坏时间复杂度为O(n),平均时间复杂度为O(n)。
    2. 对于删除操作而言:与插入操作类似,当删除第k个数据时,为了保持数组内存空间的连续性,避免出现内存空洞现象,需要将第k~n个数据依次向前腾挪一位。其最好时间复杂度为O(1),最坏时间复杂度为O(n),平均时间复杂度为O(n)。
    3. 综上可见,无论插入还是删除都会出现大规模的数据搬移现象。而链表就不会出现这种数据搬移现象。因此链表更适合插入删除操作。
    4. 在一些实际应用场景中,对于要删除的数据,并不是首先就将其从内存空间中删除,而是先将其标记,当内存满了的时候,在将这些标记删除的数据进行删除,这样就减少了数据搬移现象,提升了效率。这也就是JVM垃圾标记回收算法的原理。
  3. 为什么大多数编程语言中,数组的下标要从0开始,而不是从1开始?

         数组随机访问的公式是a[n]_address=base_address+n*data_type_size。

         当从1开始访问的公式是a[n]_address=base_address+(n-1)*data_type_size。

        可以发现,下标从1开始进行访问的结果就是,每进行一次访问,就多了一次减肥计算,cpu就多了一次减法指令。因此 更优的做法就是下标从0开始。

4.二维数组的寻址方式,对于m*n的数组:a[i][j](i<m,j<n)_address=base_address+(i*n+j)*data_type_size。

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值