数组——为什么下标从0开始呢?

什么?

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

特点

  • 数组支持随机访问。
  • 数组的 插入删除 操作比较低效。

随机访问

根据寻址公式:array[i] = base_address+i*data_type_size迅速找到对应下标 i 中数据,随机访问时间复杂度为O(1)。

插入操作

  • 最好情况:插在末尾,时间复杂度为O(1);
  • 最坏情况:插在开头,时间复杂度为O(n);
  • 一般情况,插在中间k位置:
    1. 如果数组存放数据有特定的顺序或关联,则涉及插入后数据的移动,考虑概率的情况,平均时间复杂度为O(n);
    2. 如果数组仅存放数据,数据没有特定顺序,则可以将k位数据移到最后,再插入k位,时间复杂度位O(1);

删除操作

  • 最好情况:删除末尾,O(1);
  • 最坏情况:删除开头,O(n)
  • 一般情况,删除中间k位置:
    1. 无论数组存放数据是否有序,删除k位的元素后需要移动k+1~n的数据,频繁的删除操作会导致频繁的数据搬移工作;
    2. 如果不追求数组中存放数据的连续性,可以将多次删除操作集中到某一次执行,每次删除操作仅仅做删除标记,每次删除记录下被删除的数据,当数组没有更多的空间,则可以触发一次真正的删除操作,这样就可以减少删除产生的数据搬移的工作。

数组越界

数组按照下标的随机访问,本质是访问基于base_address做偏移量的计算得到的内存地址,只要这块内存可以使用,那么即使下标已超出数组长度,程序也不会报错。例如下面的C程序:

int main(int argc, char* argv[]){
    int i = 0;
    int arr[3] = {0};
    for(; i<=3; i++){
        arr[i] = 0;
        printf("hello \n");
    }
    return 0;
}

但是不是所有的高级语言如C一样把检查数组越界的工作丢给程序员,Java就对数组越界问题做了检测,会抛出 java.lang.ArrayIndexOutOfBoundsException异常。

	public static void main(String[] args) {
        int[] arr = new int[3];
        arr[0]=11;
        for(int i=0;i<=3;i++){
            arr[i]=0;
            System.out.println("hello ");
        }
    }

Java中容器类ArrayList和数组

  • ArrayList 将很多数组操作的细节封装了起来,比如数组的插入、删除时需要搬移其他数据等;
  • ArrayList支持动态扩容,当空间不够时会自动扩容至当前的1.5倍,扩容涉及到内存空的申请等操作比较耗时,所以最好可以提前指定大小。
  • ArrayList无法存储基本数据类型,例如int、double等,需要用封装类,这里就涉及到自动装箱和拆箱或有一定的性能损耗,如果特别关注性能或者希望使用基本类型,就可以用数组。
  • 多为数组Object[][]相比ArrayList<ArrayList< Object > > 更加直观。
  • 业务开发中,我们可以直接使用容器类,如果是特别底层的开发,直接使用数组可能会更合适。

熄灯

这下应该指导为什么一般数组下标不从1开始而从0开始了吧!下标其实就是偏移量,如果从1开始的话寻址的时候还需要做i-1这样的操作,这就需要执行一次减法指令,像这么基础的数据结构,当然追求极致的性能,所以从0开始比较合理。(其实第一个人是从0开始的,后面大家都跟着用习惯了!!!)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小技工丨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值