数组
- 数组
-
- 数组定义
- 表现形式
- 数组的随机访问
-
- 数组下标为什么从0开始?
- 优缺点
- ArrayList和数组
- 堆栈内存
- 数组实现CRUD
数组
- 是有序的元素序列。若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量也称为数组的分量,也称数组元素。
- 区分数组的各个元素的数组编号为下标;
- 数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按无序的形式组织起来的一种形式。这些无序排列的同类数据元素的集合称为数组。
- 线性表
数组定义
- 数组是相同数据类型的元素的集合
- 各元素的存储是有先后顺序的,在内存中按照先后顺序存放在一起;
- 数组元素用整个数组的名字和它自己在数组中的顺序位置来表示。例如,a[0]表示名字为a的数组中的第一个元素,a[1]代表数组a的第二个元素,以此类推。
表现形式
- 一维数组
int a[],String a[]
- 多维数组
int a[][],int[][][];
数组的随机访问
数组是连续的内存空间和相同类型的数据。正是因为这两个限制,它才有了一个非常重要的特性:随机访问。但有利就有弊,这两个限制也让数组的很多操作变得非常低效,比如要想在数组中删除、插入一个数据,为了保证连续性,就需要做大量的数据搬移工作。
因此、用户可以直接根据数组下标访问数组元素
数组下标为什么从0开始?
int a[]=new int[3];
假如到内存中申请空间:10001,10005,10009。
a[0]=>10001==>10001+0 * 4;
a[1]=>10005==>10001+1 * 4;
a[2]=>10009==>10001+2 * 4;
如果我们不从0开始
a[1] = 10001+(1-1) * 4
a[2] = 10001+(2-1) * 4
a[3] = 10001+(3-1) * 4
在CPU里,一个相减运算倒没什么,但是这个运算被大量使用,就会耗费时间。所以数组下标应该从0开始;
二位数组arr[m][n]的寻址是怎么样的?
int arr[][]=new arr[m][n];
地址=数组的起始地址+m * n * typeSize+ n*typeSize;
优缺点
优点:随机访问
缺点:
- 删除、删除需要涉及到元素移动、数据量大很麻烦;
- 可能会有越界问题
ArrayList和数组
本质是一样的,都是数组。
- ArrayList是JDK封装了。不需要管扩容等操作。
- 数组的话就要你全部操作。
两者之间应该如何选用?
- 不知道数据大小的肯定选ArrayList。
- 如果你知道数据的大小而且你又非常关注性能那就用数组。
数组最需要注意的就是越界:尤其是在开始和结束。测试的时候也一样注意头和尾。
堆栈内存
Java分为堆栈两种内存。
什么是堆内存?
- 存放new创建的对象和数组。
什么是栈内存?
- 引用变量
堆栈的区别
- 栈的速度要快
- 栈内存的数据可以共享,主要存一些基本数据类型。
数组实现CRUD
package algorithm.array;
public class ArrayTest {
private int size; //数组的长度
private int data[];
private int index; //当前已经存的数据大小
public ArrayTest(int size){ //数组的初始化过程
this.size = size;
data = new int[size]; //分配的内存空间{0,0,0,0,0}
index = 0;
}
public void print(){
System.out.println("index:" + index);
for(int i = 0 ; i < index ; i++){
System.out.print(data[i] + " ");
}
System.out.println();
}
public void insert(int loc,int n){ //时间复杂度 O(n);
if(index ++ < size){
for(int i = size - 1; i > loc ; i --){ //为什么不能写size 0~size-1 如果loc是0 O(n),O(1)=>O(n)
data[i] = data[i - 1]; //把数据往后移一个
}
data[loc] = n;
}
//扩容 会把size/2;
}
public void delete(int loc){ //O(n)
for(int i = loc ; i < size ; i++){
if(i != size - 1){ //怕越界所以加一个判断
data[i] = data[i + 1];
}else{
data[i] = 0; //默认为0 就是没存数据的
}
}
index -- ;
}
public void update(int loc,int n){//O(1)
data[loc] = n;
}
public int get(int loc){ //O(1)
return data[loc];
}
public static void main(String[] args) {
//ArrayList
}
}
其实这就类似ArrayList的底层实现;