数组基本语法
定义:数组是相同类型的数据按顺序组成的一种引用数据类型
作用:用于将相同数据类型的多项数据存储在连续的存储单元中
数组声明
语法:数组类型[] 数组名; 或数组类型 数组名[];
例如:int[] myIntArray; int myIntArray[];
数组名:是数组空间的引用,它指向了数组空间的首地址(第一个元素)-
数组创建
语法一:先声明后创建数组类型[] 数组名;
数组名 = new 数据类型[数组长度];
例如:int[] arr;
arr = new int[10];
//创建一个10个元素的数组对象,并把对象的引用赋给arr语法二:声明的同时创建数组
数组类型[] 数组名 = new 数据类型[数组长度];
例如:int[] arr = new int[10];
注意:创建数组时数组长度必须指定 -
数组元素初始值
数组会被分配连续的内存空间,且针对不同数据类型会赋予数组每个元素一个固定的初始值(默认值)。 数组的初始化
声明数组的同时给数组赋值,叫做数组的初始化。数组的长度就是初始化时所给数组元素的个数。
初始化方式:
int[] arr = {1,2,3,4,5};
//静态初始化,初始化长度为5的整型数组
int[] arr = new int[]{1,2,3,4,5};
//用new声明的同时初始化-
数组元素的引用
语法:数组名[下标]; //下标从0开始
数组长度:属性length表示数组的长度,如
a.length;
数组下标越界
数组下标范围为[0 - arr.length - 1], 一旦操作不在这个范围的下标元素,则会抛出异常,异常为ArrayIndexOutOfBoundsException
,表示数组下标越界。数组的访问与赋值
对于数组而言,使用循环遍历即可依次访问或者修改数组的每个元素
//创建数组
int[] intArray = new int[5];
//循环为数组赋值
for (int i = 0; i < intArray.length; i++) {
intArray[i] = i + 1;
}
//循环输出数组中的元素:1 2 3 4 5
for (int i = 0; i < intArray.length; i++) {
System.out.print(intArray[i] + " ");
}
数组基本算法
1. 数组求和
数组求和非递归方式实现
// 初始化数组
int[] intArray = { 1, 2, 3, 4, 5, 6 };
int sum = 0;
// 求和
for(int i = 0; i < intArray.length; i++) {
sum += intArray[i];
}
System.out.println("数组的和为:" + sum);
数组求和递归方式实现:
Sum( arr[0...n-1] ) = arr[0] + Sum( arr[1...n-1] )
--> 将问题转换为更小的同一问题
Sum( arr[1...n-1] ) = arr[1] + Sum( arr[2...n-1] )
-->
递归逻辑:规律就是当前数组的和等于第一个元素 + 从下一个索引开始新的数组的和
依此类推:
Sum( arr[n-1...n-1] ) = arr[n-1] + Sum( arr[] )
-->最基本的问题,递归出口
public static int sum(int[] arr){
return sum(arr, 0);
}
//计算arr[l...n)这个区间内所有数字的和
private static int sum(int[] arr, int l){
if(l == arr.length){
return 0;
}
//递归调用
return arr[l] + sum(arr, l + 1);
}
public static void main(String[] args) {
int[] nums = {1,2,3,4,5,6,7,8,9,10};
System.out.println(sum(nums)); //55
}
2. 数组最大最小值
// 初始化数组
int[] intArray = { 1, 2, 3, 4, 5, 6 };
//最大最小值默认为第一个元素
int max = intArray[0];
int min = intArray[0];
for(int i = 0; i < intArray.length; i++) {
// 总是将最小的元素值赋给min变量
if (intArray[i] < min) {
min = intArray[i];
}
// 总是将最大的元素值赋给max变量
if (intArray[i] > max) {
max = intArray[i];
}
}
System.out.println("数组的最大值为:" + max); //6
System.out.
3. 冒泡排序
对一组整数按照由小到大的顺序进行排序
原理:比较两个相邻的元素,将值大的元素交换至右端
思路:依次比较相邻的两个数,将小数放在前面,大数放在后面。对于第一趟需要比较到最后两个元素,此时数组最后一个数一定是最大值,第二趟就不需要比较最后一个数了,从第一个数比较到倒数第二个数,第二趟结束第二大的数就确定了,依此类推,每次比较次数-1,直到最后比较次数为1,整个数组就从小到大排序好了。
结论:对于N个元素的数组要排序完成,总共进行N-1趟排序,每i趟的排序次数为(N-i)次,可以用双重循环语句,外层控制循环多少趟,内层控制每一趟的循环比较次数。
图示:
实现:
//冒泡排序
private static void sort(int[] arr) {
//外层循环控制排序趟数
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]) {
//交换值
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
public static void main(String[] args) {
// 初始化数组
int[] arr = { 34, 53, 12, 32, 56, 17 };
sort(arr); //排序
//[12, 17, 32, 34, 53, 56]
System.out.println(Arrays.toString(arr)); //调用工具类打印数组
}
4. 选择排序(简单选择排序)
原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。
区别:冒泡排序是相邻的两个元素进行比较和交换,而选择排序则是选取一个元素与其他所有元素进行比较和交换。
思想:给定数组:int[] arr={里面n个数据}; 第1趟排序,在待排序数据arr[1]~arr[n]中选出最小的数据,将它与arr[1]交换;第2趟,在待排序数据arr[2]~arr[n]中选出最小的数据,将它与arr[2]交换;以此类推,第i趟在待排序数据arr[i]~arr[n]中选出最小的数据,将它与arr[i]交换,直到全部排序完成。
实现:
//选择排序
private static void sort(int[] arr) {
//外层循环代表轮数,代表正在比较第几小的数
for(int i=0; i<arr.length-1; i++){
//比较这一个数出来,需要比较多少次
for(int j=i+1; j<arr.length; j++){
//如果按照从小到大的顺序,则需要前边的数比后边的数小
if(arr[i]>arr[j]){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
public static void main(String[] args) {
// 初始化数组
int[] arr = { 34, 53, 12, 32, 56, 17 };
sort(arr); //排序
//[12, 17, 32, 34, 53, 56]
System.out.println(Arrays.toString(arr)); //调用工具类打印数组
}
优化:上述代码是每次排序都需要和其他元素进行比较并且满足条件则交换,那么其实我们只需要找出其他元素中最小的值并记录它的索引,之后将该索引对应的元素与当前选择的元素进行比较和交换判断即可。避免了过多的交换操作。
private static void sort(int[] arr) {
for(int i=0; i<arr.length-1; i++){
//k用来记录其他元素中最小值的索引
int k = i;
for(int j=i+1; j<arr.length; j++){
if(arr[k] > arr[j]){
k = j;
}
}
//在内层循环结束,也就是找到本轮循环的最小的数以后,再进行交换
if(k != i){
int temp = arr[k];
arr[k] = arr[i];
arr[i] = temp;
}
}
}