数据结构与算法之美-数组笔记

数组:为什么很多编程语言中数组都从0开始编号?

定义

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

  • 线性表
  • 连续的内存空间和相同类型的数据

一些解答

从数组存储的内存模型上来看,“下标”最确切的定义应该是“偏移(offset)”。如果用 a 来表示数组的首地址,a[0]就是偏移为 0 的位置,也就是首地址。

另外由于历史原因,c之后的一些高级语言都遵循c的从0开始的计数习惯。减少了学习成本。

问题:数组和链表的区别

错误回答:链表适合插入、删除,时间复杂度 O(1);数组适合查找,查找时间复杂度为 O(1)。
错误原因:数组查找的时间复杂度不是O(1),即使是排好序的数组,你用二分查找,时间复杂度也是 O(logn).
正确的表述:数组支持随机访问,根据下标随机访问的时间复杂度为 O(1)。

警惕数组的访问越界问题

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

在 C 语言中,只要不是访问受限的内存,所有的内存空间都是可以自由访问的。根据我们前面讲的数组寻址公式,a[3]也会被定位到某块不属于数组的内存地址上,而这个地址正好是存储变量 i 的内存地址,那么 a[3]=0 就相当于 i=0,所以就会导致代码无限循环。

容器类VS数组

针对数组类型,很多语言都提供了容器类,比如 Java 中的 ArrayList、C++ STL 中的 vector。

  • 可以将很多数组操作的细节封装起来。
  • 支持动态扩容。
  • 最好在创建 ArrayList 的时候事先指定数据大小。

数组更合适的情况:

  1. Java ArrayList 无法存储基本类型,如果特别关注性能,或者希望使用基本类型,就可以选用数组。
  2. 如果数据大小事先已知,并且对数据的操作非常简单,使用数组更方便。
  3. 表示多维数组时,用数组往往会更加直观。比如 Object[][] array;而用容器的话则需要这样定义:ArrayList<ArrayList > array。

总的来说,业务开发使用容器类比较省力,底层重性能的开发还是使用数组。

总结

  1. 数组用一块连续的内存空间,来存储相同类型的一组数据。
  2. 最大的特点就是支持随机访问,但插入、删除操作也因此变得比较低效,平均情况时间复杂度为 O(n)。
  3. 在平时的业务开发中,我们可以直接使用编程语言提供的容器类,但是,如果是特别底层的开发,直接使用数组可能会更合适。
发布了19 篇原创文章 · 获赞 1 · 访问量 234

猜你喜欢

转载自blog.csdn.net/helen920318/article/details/104824393
今日推荐