目录
一. 一维数组
1.数组概述:
数组(array):是一种用于存储多个相同数据类型的存储模型(可以理解为容器)。
( 一次性声明大量的用于存储数据的变量, 要存储的数据通常都是同类型数据,
例如:考试成绩 int[] scores = {100,100,100,100,100,100,100…};)
2.数组的定义格式:
格式1:数据类型[] 变量名; 范例: int[] arr;
定义了一个int类型的数组,数组名是arr
格式2:数据类型 变量名[]; 范例: int arr[];
定义了一个int类型的变量,变量名是arr数组
推荐使用:格式1
3.数组初始化:
(1)数组初始化概述:Java中的数组必须先初始化,然后才能使用,
所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值。
注意:数组中的每一个数据,我们称之为数组中的元素。
(2)数组初始化方式:
静态初始化:初始化时指定每个数组元素的初始值,由系统决定数组长度
格式:数据类型[] 变量名 = new 数据类型[]{数据1,数据2,数据3,…};
范例:int[] arr = new int[]{1,2,3};
简化格式:数据类型[] 变量名 = {数据1,数据2,数据3,…};
范例:int[] arr = {1,2,3};
动态初始化:只声明数组的长度,不赋值。
格式:数据类型 [] 变量名 = new 数据类型[数组长度];
eg. int [] arr = new int [3];
注意:动态初始化时,只声明了数组的长度,但系统会给数组分配默认值,整数型为0,浮点数为0.0,字符型默认为空字符 '\0',布尔类型为false,引用类型为null
4. 数字元素访问:
数组变量访问方式:数组名
数组内部保存的数据的访问方式:数组名[索引]
索引是数组中数据的编号方式
作用:索引用于访问数组中的数据使用,数组名[索引]等同于变量名,是一种特殊的变量名
特征①:索引从0开始
特征②:索引是连续的
特征③:索引逐一增加,每次加1
public class ArrayTest {
public static void main(String[] args) {
int [] arr = {1,2,3,4};
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
}
5. 数组操作
(1)遍历:获取数组中的每一个元素,我们可以把获取到的元素输出在控制台。
获取数组长度(元素个数) 格式:数组名.length
范例:arr.length
(2)获取最大值:
(3)元素打乱:
6. 内存分配
先简要得介绍一下java中的栈和堆,java的运行时内存可分为堆内存,栈内存,方法区和本地方法栈,栈中保存的是局部变量;堆中保存的是一些动态产生的数据,比如new出来的对象。
7.可能出现的异常
(1)数组越界(ArrayIndexOutOfBoundsException)
访问了不在数组索引范围内(o~length-1)的元素
(2)空指针异常
访问的数组不再指向堆内存中的数据
二. 二维数组
1.二维数组概述:元素为一维数组的数组
2.二维数组初始化
3. 二维数组元素访问
4.二维数组内存图
5.二维数组操作:
(1)遍历
三. 一维数组常见操作
1.遍历
for循环遍历
public static void PrintArr(int [] arr){
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i];)
}
}
}
for each遍历
public class ArrayTest {
public static void main(String[] args) {
int [] arr = {1,2,3,4};
PrintArr(arr);
}
public static void PrintArr(int [] arr){
for (int i : arr) {
System.out.println(i);
}
}
}
2.找最大值
public static int GetMax(int [] arr){
if (arr!=null ){
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]){
max = arr[i];
}
}
return max;
}
else
return -2147483648;
3.插入元素
前提条件:数组有足够的空间容纳插入元素
public static void insert(int[] arr, int num, int index, int count) {
/*
num:插入的值
index:插入下标
count:当前数组数据个数
*/
int temp;
// 预计插入位置不在数组索引范围内
if (index >= arr.length){
System.out.println("***");
return;
}
// 在没有元素的位置插入
if(index > count)
arr[index] = num;
else{
// 在有元素的序列中插入,从插入位置开始,整体后移
for (int i = count; i > index; i--) {
arr[i] = arr[i - 1];
}
arr[index] = num;
}
}
4.删除
public static void del(int []arr, int num){
for (int i = 0; i <arr.length; i++) {
if (arr[i] == num){
for (int j=i;j<arr.length-1;j++){
arr[j] = arr[j+1];
}
}
}
}
5.修改
已知下标的情况,直接赋值即可。
如果是有序序列,可通过二分查找找出元素的下标,再进行修改
public static void modfiy(int[] arr,int srcNum, int newNum){
for (int i = 0; i < arr.length; i++) {
if (arr[i] == srcNum){
arr[i] = newNum;
}
}
}
6.二分查找
前提:数组是有序的,要查找的元素只有一个
执行的操作:(1)在有序序列中,开始位置定义为左节点,结束位置右节点,并计算出中间节点 (2)判断中间节点对应值和待查找key值得关系,相等就返回中间节点并结束查找,大于将右节点更新为中间节点-1,小于将左节点更新为中间节点+1。(3)重复上面两步,直到左节点大于右节点。
target(查找元素):7
arr(查找数组) = {1,3,5,7,9,11,14,22,29};
代码实现
/*key(查找元素):7
arr(查找数组) = {1,3,5,7,9,11,14,22,29};*/
//声明一个数组
int[] arr = {1, 3, 5, 7, 9, 11, 14, 22, 29};
//将你要在数组中查找的数赋值给变量target
int target = 7;
//左指针一开始指向数组的第一位数的下标
int left = 0;
//右指针一开始指向数组的最后一位数的下标
int right = arr.length - 1;
int mid;
boolean flag = true;
//因为是[]左右都闭合区间,left可以等于right,因此判断条件为left <= right
while (left <= right) {
//中指针指向数组左指针和右指针最中间的那个数的下标
mid = (left + right ) / 2;
if (target == arr[mid]) {
//如果要查找的数等于中间指针指向的数,则找到这个数,退出循环
System.out.println(mid);
flag = false;
break;
} else if (target > arr[mid]) {
/*如果要查找的数大于中间指针指向的数,说明这个数只可能
在mid的右边,因为target已经大于arr[mid],必不可能再等于
,因此从mid右边一个数开始继续查找*/
left = mid + 1;
} else {
/*如果要查找的数小于中间指针指向的数,说明这个数只可能
在mid的左边,因为target已经小于arr[mid],必不可能再等于
,因此从mid左边一个数开始继续查找*/
right = mid - 1;
}
}
if (flag) {
System.out.println("数组中不存在这个数");
}
7.排序
冒泡排序
public static void bubble(int []arr){
/*
* @param:arr 待排序数组
* @ return
*
*/
int temp;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length-1-i; j++){
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
选择排序
//选择排序:选择一个最值(最大或最小),遍历数组,根据大小和最值交换位置
//声明一个无序数组
int[] arr = {9, 11, 8, 6, 4, 2, 1};
//声明一个最小值的索引变量,初始化为数组第一个数下标
int minIndex;
//声明一个暂存变量,方便数组交换位置
int temp;
//for循环找到最小值的索引,外层循环将最小值放到最前面,内存循环找到最小值索引
for (int i = 0; i < arr.length; i++) {
//最小值的索引的索引为当前循环的第一个值
minIndex = i;
//内存循环找到最小值的索引,每找到一次最小值并将它放到数组元素最前面,
// 下一次就从它的后一个位置开始重新找最小值
for (int j = i; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
//将每次找到的最小值和当前循环的第一个值交换位置
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
//遍历打印输出排序好的数组元素
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
插入排序
public static void insertSort(int []arr){
/*
* @param:arr
* @ return:
*/
// 假定我们手中的牌是3 2 9 7 5
// 从3开始假定其有序,2的时候,发现2<3,就和3交换 2 3 9 7 5
// 9的时候,我们发现它大于前面的牌,不动
//...
// 2 3 7 9 5 ,5比前一个数9小,交换得 2 3 7 5 9,5依然小于 7 ,再次交换,发现5>3,停止交换
int temp;
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = i+1; arr[j] < arr[j-1]; j--) {
// 和前一个元素进行交换
ArrayUtils.swap(arr,j,j-1);
}
}
}
快速排序
public static void quickSort(int []arr, int left, int right){
/*
快排规则
找出一个数作为数轴,双指针向数周靠拢,大于放右边,小于放左边
排一次,然后对左边右边分别递归执行上述步骤,直到子序列中的元素较少,使用插入排序
如果一直使用快速排序,结束条件为枢轴左侧或右侧只有一个数据
* @param:
* @ return:
*/
// 数组为空或只有一个元素,不做处理
if (arr == null || arr.length == 1 ){
return;
}
// 数组元素小于10,使用插入排序
if (right - left < 10)
InsertSort.insertSort(arr, left, right);
// 进行快排
// 找出中轴位置,并进行排序
else{
int centerAxis = firstSort(arr, left, right);
// int centerAxis = firstSort1(arr, left, right);
// 结束第一次排序,分别对两个子序列进行排序
quickSort(arr, left,centerAxis-1);
quickSort(arr, centerAxis+1,right);}
}
public static int firstSort(int [] arr, int left, int right){
// 左右指针法实现第一次排序
// 实现思路,left 往右找,直到找到一个大于key的值,停下
// right往左找,找到一个小于key的值,停下
// right 和 left交换
// 直到 right<= left
// 结束第一次排序
// int keyIndex = left;
// System.out.println(left);
int key = arr[left++];
while(left < right){
while(arr[left]<=key && right> left)
left++;
while (arr[right]>=key && right > left )
right--;
// 分别找到了左边大于key,右边小于key的值,交换
ArrayUtils.swap(arr,left,right);
}
ArrayUtils.swap(key, left);
return left;
}
// 挖坑进行第一次排序找出中轴
public static int firstSort1(int []arr, int left, int right ){
int key = arr[right];
// 实现思路,取出最右边值为中枢,从左开始找,找到>key的值放到,right所在处,接着停下
// right开始找,找到<key的,放到left处
while (left < right){
while(arr[left] <= key && left < right )
left ++;
arr[right] = arr[left];
while (arr[right] >= key && left < right)
right --;
arr[left] = arr[right];
}
arr[right] = key;
return right;
}
}
四. 一维数组常见案例
1.打印一个三角形
//打印一个等腰三角形 /* * *** ***** ******* ********* */ //打印5行 for (int i = 1; i <= 5; i++) { //每行打印空格,第一行打印4个,下一行依次-1个 for (int j = 1; j <= 5 -i; j++) { System.out.print(" "); } //打印*,第一行打印1个,第二行打印3个,第三行打印5个,即每行打印:当前行数*2-1个 for (int k = 1; k <= 2*i-1; k++) { System.out.print("*"); } //打印完一行就换行 System.out.println(" "); }
//打印一个倒三角形
/* *********
*******
*****
***
* */
//打印5行
for (int i = 0; i < 5; i++) {
//每行打印空格,第一行打印0个,第二行1个,第三行2个,即当前行数-1个
for (int j = 0; j <= i-1; j++) {
System.out.print(" ");
}
//打印*,第一行打印9个,第二行打印7个,第三行打印5个,即每行打印:9-2*i
for (int k = 0; k < 9-2*i; k++) {
System.out.print("*");
}
//打印完一行就换行
System.out.println(" ");
}
//打印空心三角形
/* *********
* *
* *
* *
* */
for (int i = 0; i < 5; i++) {
//每行打印空格,第一行打印0个,第二行1个,第三行2个,即当前行数-1个
for (int j = 0; j <= i - 1; j++) {
System.out.print(" ");
}
//打印*,第一行打印9个,第二行打印7个,第三行打印5个,即每行打印:9-2*i
for (int k = 0; k < 9 - 2 * i; k++) {
//如果是第一行,就整行打印*
if (i == 0) {
System.out.print("*");
}
//从第二行开始是每一行的第一个或最后一个就打印*,否则打印空格
else if (k == 0 || k == 9 - 2 * i - 1) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
//打印完一行就换行
System.out.println(" ");
}
2.杨辉三角
//杨辉三角
/* 1
11
121
1331
14641*/
// 打印一个10行的杨辉三角
/*杨辉三角特点:
1.是第几行则有几个数
2.第1行和第2行都是1
3.从第三行开始,除了每一行的第一个数和最后一个数是1,中间的数等于它上一行相同位置和前一个位置的数的和*/
//首先声明一个二维数组,一维数组(即行数)给它动态初始化一个值,二维数组(即列数),因为每一行的列数不同,后面通过循环动态初始化和赋值
int[][] arr = new int[10][];
//通过循环给二维数组动态初始化,规定数组长度,第一行为1,第二行为2,依次递增
for (int i = 0; i < arr.length; i++) {
//给每一行的数组开空间
arr[i] = new int[i + 1];
for (int j = 0; j < arr[i].length; j++) {
//给每一行的数组赋值
//如果是一行的第一个是或是最后一个数,则直接赋值为1
if (j == 0 || j == arr[i].length - 1) {
arr[i][j] = 1;
} else {
//否则,即是一行中间的数,则
arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
}
}
}
//遍历数组打印输出
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + "\t");
}
System.out.println(" ");
}