zoukankan      html  css  js  c++  java
  • 数组

    数组与链表的区别

    随机访问是数组与链表最本质的区别,而“数组适合查找,链表适合插入和删除”这种表述并不准确。数组查找的时间复杂度并不为O(1),即使排好序的数组,使用二分查找,时间复杂度也是O(logn)。数组支持随机访问,根据下标随机访问的时间复杂度为 O(1)

    数组特性

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

    线性表

    每个线性表上的数据最多只有前和后两个方向

    非线性表数据之间关系就会复杂很多,比如二叉树,堆,图。

    连续的内存空间和相同类型的数据

    随机访问正是因为这两个特性才能实现。这也导致删除和插入的时候,需要做大量数据搬移的工作。

    如何根据下标随机访问数组元素

    假设有有一个数组 int[] a = new int[10],内存块首地址为base_address = 1000.

    根据寻址公式来计算该元素存储的内存地址:(data_type_size 表示数组中每个元素的大小)

    a[i]_address = base_address + i * data_type_size

    数组的插入

    数组插入的平均时间复杂度为O(n),因为最坏情况需要移动所有的元素。

    想要降低复杂度可以将要插入位置的旧元素挪到数组尾部,然后将新元素插入即可。

    数组的删除

    删除元素后一样会伴随搬移数据,为了保证内存的连续性。平均时间复杂度也为O(n).

    特殊场景下可以把删除操作集中到一起执行,也就是每次删除操作并不是真正搬移数据,只是记录数据已经被删除。当数组没有更多空间存储时,再触发一次真正的删除操作,这样就大大减少了删除操作导致的数据搬移。JVM的标记清除算法就是如此。

    容器与数组

    容器(例如ArrayList)的最大优势就是可以将很多数组操作的细节封装起来,另外就是支持动态扩容,ArrayList不设默认长度时候,则先默认设置10的内存空间,之后如果长度大于10则扩容1.5倍,同时复制数组。

    1. 容器无法储存基本类型,如果要使用基本类型可以使用数组
    2. 底层开发可以为了性能考虑可以使用数组。

    数组下标为什么从0开始

    之前的寻址公式为:

    a[k]_address = base_address + k * type_size

    如果数组下标是从1开始,那么寻址公式就会变为:

    a[k]_address = base_address + (k - 1) * type_size

    每次随机访问元素都多了一次减法运算,对于CPU来说,就多了一次减法指令。

  • 相关阅读:
    define vs const vs enum
    解决Ubuntu 14.04 LTS 浏览网页速度慢的问题
    C语言两种产生矩阵的方法
    GTK 添加图标
    Unix Socket 端口 reuse
    Linux GTK Hello,World
    插件使用记录
    原型链和new
    each函数循环数据表示列举,列举循环的时候添加dom的方法
    字体圆润属性的使用-webkit-font-smoothing: antialiased
  • 原文地址:https://www.cnblogs.com/zhaozihan/p/13251977.html
Copyright © 2011-2022 走看看