java基础笔记004
今日内容
1. 【理解】 什么是数组
2. 【掌握】 数组的定义及初始化
3. 【理解】 数组的内存图
4. 【理解】 数组常见的问题
5. 【掌握】 数组的案例
6. 【理解】 二维数组
一、一维数组
数组就是存储长度固定、 存储数据类型相同的容器。
数组可以存储所有数据类型!
- 1.数组的基本语法(定义+初始化),
- 静态初始化:初始化时直接给数组元素赋值,由系统计算出数组长度。
- 动态初始化:初始化时只给出数组的长度,有系统给出默认初始化值。
//定义 = 初始化 :可随机搭配
数据类型[] 数组名 = new 数据类型[数组长度]; //动态初始化
数据类型 数组名[] = new 数据类型[]{数组元素0,数组元素1,...}; //静态初始化
数据类型[] 数组名 = {数组元素0,数组元素1,...}; //静态初始化
-
2.数组的存储结构
-
栈中放的是变量名,对于引用数据变量其存储的是对重对象或数组的地址值(String以String s = “das”;使用时例外)。对于基本数据类型变量名存放的是常量的地址。
-
堆中存放的是new出来的对象和数组,部分值为常量池中的常量的地址,也可能是方法区中方法的地址。
-
常量池存放的是常量,是值,不是地址。
-
-
3.动态初始化时数组的默认值
数据类型 | 默认初始值 |
---|---|
byte/short/int/long | 0 |
float/double | 0.0 |
char | 一个空字符,即’\u0000’ |
boolean | false |
引用数据类型 | null,表示变量不引用任何对象 |
- 注意:
- 数组的索引都是从0开始,范围都是 0~(length-1)。
- 数组长度固定,超出索引范围会报异常(ArrayIndexOutOfBoundsException)。
- 常用属性,length。数组长度
int[] arr = {4,3,5,1};
for(int i=0; i<=arr.length-1; i++){ //索引从0开始,索引范围0-3
System.out.println(arr[i]);
}
System.out.println(arr[arr.length]); //该行报错,索引越界!!!
二、多维数组
- 多维数组的语法:
//常用的就是二维数组,几维数组定义是就对应几个[]
int[][] arr = new int[3][5];
int[][] arr = new int[3][];
int[][] arr = {{1,2},{3,4,5},{2,1,3}};
-
理解使用:
二维数组就相当于一个矩阵,当要使用某一元素时需要两个索引,第一个索引代表行,第二个索引代表列,都是从0开始。
int[][] arr = new int[2][3];
arr[1][1] = 5; //将第二行第二个元素赋值为5
//数组对应索引
/*
[0][0] [0][1] [0][2]
[1][0] [1][1] [1][2]
*/
三、数组练习
- 遍历
int[][] arr2 = {{1,2},{3,4,5},{6,7}};
for(int i=0; i<arr2.length; i++){ //二维数组中数组名.length表示行数
for(int j=0; j<arr2[i].length; j++){
System.out.print(arr2[i][j]+" ");
}
System.out.println();
}
/*
1 2
3 4 5
6 7
*/
- 排序
使用冒泡排序算法,进行对一数组进行从小到大排序。
算法:解决某类问题的一种思路。
//冒泡排序算法
1.从前到后依次比较相邻两个数组元素,如果后一个大,则两者互换
2.每次循环确定剩余待排序元素中的最大值,方法待排序位置的最后
3.重复1步骤
int [] arr = {32,12,2,4,-3,22};
for(int i=1; i<arr.length; i++){ //只需要循环length-1次
for(int j=0; j<arr.length-i; j++){
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
还有选择排序、快速排序、归并排序、插入排序等
选择排序
个人理解:每次大循环都找出最大值,把他放到最后一位,每次大循环后下次再小循环时循环长度减一,因为最后一个已经排好固定了
//选择排序算法
int [] arr = {12,2,-1,22,10};
int max;
for(int i=1; i<arr.length; i++){
max = arr[0];
int index = 0;
//寻找本轮最大值
for(int j=1; j<arr.length-(i-1); j++){
if(max < arr[j]){
max = arr[j];
//标记本轮最大值的下标
index = j;
}
}
//看最后(除去排好顺序的)一个是否正好最大
if(index != arr.length-i){
int temp = arr[index];
arr[index] = arr[arr.length-i];
arr[arr.length-i] = temp;
}
}
插入排序
个人理解:小 --> 大
- 1.将0索引位置数据看作已经排好序
- 2.从下个索引开始向前比较,如果比自己大则互换
- 3.如果碰到比自己小的或相等停下来
- 4.重复2-3步骤,直到执行到最后一个数值
//插入排序
int[] a = {4,-2,3,2,1};
//外循环次数
for(int i=0; i<a.length-1; i++){
int nu = a[i+1];
int preIndex = i+1;
//将该数与前面所有进行比较
for(int j=i; j>=0; j--){
//比前面小,则互换
if(nu < a[j]){
int temp = a[preIndex];
a[preIndex] = a[j];
a[j] = nu;
preIndex = j; //如果以换位置,记录操作元素最新位置下标
}else{
break; //如果前面的数小于等于操作数,退出本次小循环
}
}
}
归并排序
个人理解:(归并排序和快速排序比较难理解,由图解比较好理解,归并排序可参考:Leo的博客-CSDN博客_归并排序java)
采用递归调用函数的方式,将数组分割成长度为1的数组,然后相邻两两进行排序并组合成一个数组,直至得到排序好的数组。
//归并排序算法
public class MergeSort {
public static void main(String[] args) {
int [] arr = {5,4,1,3,2};
int [] tmp = new int[arr.length]; //创建一个空数组,用于整合数组
mergeSort(arr, 0, arr.length-1, tmp);
for(int i=0; i<arr.length; i++){
System.out.print(arr[i]+" ");
}
}
public static void mergeSort(int[] arr,int low,int high,int[]tmp){
if (low<high) {
int mid = (low+high)/2;
mergeSort(arr, low, mid, tmp);
mergeSort(arr, mid+1, high, tmp);
merge(arr, low, mid, high, tmp);
}
}
public static void merge(int[] arr,int low,int mid,int high,int[] tmp){
int i = 0;
int j=low,k=mid+1; //左序列和右序列的起始索引
//合并序列
while(j<=mid && k<=high){
if (arr[j]>arr[k]) {
tmp[i++] = arr[k++];
}else{
tmp[i++] = arr[j++];
}
}
//将左序列或右序列中剩余元素放入中间数组
while(j<=mid){
tmp[i++] = arr[j++];
}
while(k<=high){
tmp[i++] = arr[k++];
}
//将合并好的序列(该段元素已排好序),放入原数组的原来位置段
for(int t=0; t<i; t++){
arr[low++] = tmp[t];
}
}
}
快速排序
个人理解:(比较复杂,可参考王玉Student的博客-CSDN博客)
- 1.以最左边元素为基数
- 2.先从右边索引依次递减,直至找到比基数小的值,停下(j=array.length-1; j–;)
- 3.从左边索引依次递增,直至找到比基数大的值,停下,(i=0; i++;)
- 4.交换两次找到的索引对应的值
- 5.重复2-3-4,到i与j停留再相同索引(i==j),将基数与当前位置元素互换
- 6.从交换后基数索引分为左右两个序列,然后分别重复1-2-3-4-5-6直到左右序列只有一个元素为止
//快速排序算法
public class QuickSort {
public static void main(String[] args) {
int [] arr = {5,4,1,3,2,9};
quickSort(arr, 0, arr.length-1);
for(int i=0; i<arr.length; i++){
System.out.print(arr[i]+" ");
}
}
//快速排序
public static void quickSort(int[] arr,int low,int high){
//只有一个元素时不再分割排序
if (low > high) {
return;
}
int js = arr[low]; //本轮基数
int i=low,j=high;
while(i<j){
//先从右边,依次向左递减
while(arr[j]>=js && i<j){
j--;
}
//再看左边,依次向右递增
while(arr[i]<=js && i<j){
i++;
}
//满足条件,互换i,j索引对应的元素
if (i<j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
//将基数位与i和j同在索引位置元素交换
arr[low] = arr[i];
arr[i] = js;
//以换后基数所在索引为界,分为左右两个序列,并分别进行递归调用
quickSort(arr, low, j-1);
quickSort(arr, j+1, high);
}
}