1.数组介绍
数组代表内存里面一组连续的同类型存储区域,并把多个存储区域合并为一个整体(寻址方式为:基地址+偏移量),数组的遍历素的最快。
int arr[10] = {0,1,2,3,4,5,7,9};
arr[4]的值为4,arr[4]的地址=arr的地址+元素标号(4),默认初始化元素的值为0.下标访问,会出现数组越界问题。
- 数组下标从0开始
- 数组下标使用数学上的左闭右开区间 [ , ) 来标识范围
2.数组操作
2.1 访问时间复杂度O(1)
// 常用的访问数据方式
for(int pos = 0: pos < 10; ++pos)
{
std::cout << arr[pos] << std::endl;
}
arr[5] = 0;
2.2 尾部添加、删除末尾时间复杂度O(1)
2.3 查找时间复杂度O(n)
// 一维数组,查找值为3的元素的下标
int arr[] = {0,1,2,3,4,5,7,9};
int len = sizeof(arr) / sizeof(arr[0]);
for(int pos = 0: pos < len; ++pos)
{
if (arr[pos] == 3)
{
std::cout << pos << std::endl;
}
}
arr[2][3] = {{0,1,3}, {0,1,4}}; // 二维数据
二维数据在内存中是按行进行存储的
二维数据的访问需要遵循的原则:按行访问,而不是按列访问。
底层思想:“空间局部性”
- 在一个小的时间窗口内,访问的变量地址越近越好,这样执行的速度快。原因分析:跨区域的地址访问,需要频繁的加载内存(CPU的多级缓存机制)
- 一般来说,需要将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数
2.4 排序
2.4.1 冒泡排序,每一趟找出最大的,总共比较次数为arr.length-1次,每次的比较次数为arr.length-i次,时间复杂度O(n²)
int arr=[1,2,5,8,11,7,9];
int len = sizeof(arr) / sizeof(arr[0]);
int temp;
for(int i = 0; i < len -1; i++){
for(var j = 0; j < len -i; j++){
if(arr[i] > arr[j]){
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}