数据结构与算法---数组

数组的定义

数组是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。

其中有几个重要的概念:

  • 线性表
    • 线性表就是数据排成像线一样的结构。每个线性表最多只有前和后两个方向。
    • 是线性表的数据结构有:
      • 数组
      • 队列
      • 链表
  • 非线性表
    • 非线性表则与线性表相反,数据并不是简单的前后关系。
    • 非线性表的数据结构有:
  • 连续的内存空间
    • 数组在内存中的存储方式是一组给定长度的连续的空间。
    • 连续的空间才使得数组可以实现通过下标随机访问。
    • 高级语言中的数组能动态扩容均是二次封装之后的结果,最底层的数据初始化的时候就已经指定好了该数组的长度。
  • 存储相同类型的数据
    • 相同类型+连续空间使得数组可以通过下标随机访问。

数组的原理

如图所示,这是一个长度为5的int数组arr,我们假设起始的内存地址为1000,那么第一个元素的内存地址范围就是:1000-1003,这是因为一个int占4个字节。那么如果我们想要访问最后元素arr[4],我们可以很容易的通过起始地址计算出来,1000+4*4 = 1016。那么最后一个元素就是内存地址1016-1019。这就是数组随机访问的原理,并且通过前面的算式,我们可以得出因为数组下标访问的计算与数组长度n无关,因此下标访问的时间复杂度为O(1)

数组的特点

  • 可以直接随机访问(依据下标访问)其中的任意数据
  • 随机访问数据非常高效
  • 低效的插入和删除

前两点上面原理里面已经解释的很清楚了,这里我们聊聊数组的插入与删除。

因为数组是一组连续的内存空间,那么不管我们是要往里面插入或者删除,都必须涉及到数组插入、删除节点之后的数据的移动。那么最理想的情况:直接在数组末尾插入、删除元素,时间复杂度为O(1)。最差情况:在数组开启插入、删除元素,时间复杂度为O(n)。因此数据的插入、删除操作是非常低效的。

操作数组的小技巧

既然我们已经知道了数组插入、删除的效率问题,那么我们可以有一些小技巧来优化我们的操作。

  • 数组插入操作:如果我们要插入的数组是一个本身就无序的数组,那么我们可以不需要将数据插到指定位置,直接插入末尾即可,这样时间复杂度为O(1),效率极高。
  • 数组删除操作:如果我们有需求涉及到频繁的删除数组中的数据,因为每次删除都会造成数据的移动,非常的消耗性能,我们可以先记录下已经删除的数据,而不是真正的从数组中删除,当数组空间不够时或者删除操作全部执行完之后,再一次性的删除全部对应的数据并移动剩余数据,这样大大减少了数据 搬移的次数,提高执行效率。(这也是JVM标记清除垃圾回收算法的核心思想)

欢迎大家关注我的个人博客:http://blog.geek-scorpion.com/

你可能感兴趣的:(数据结构与算法)