数组常见算法有以下几种:
1.数组元素的赋值(杨辉三角、回形数等)
1.1创建一个长度为6的int型数组,要求取值为1-30,同时元素值各不相同
package Array;
public class ArraySF_Random {
public static void main(String[] args) {
// 方式一:
// int[] arr = new int[6];
// for (int i = 0; i < arr.length; i++) {// [0,1) [0,30) [1,31)
// arr[i] = (int) (Math.random() * 30) + 1;
//
// boolean flag = false;
// while (true) {
// for (int j = 0; j < i; j++) {
// if (arr[i] == arr[j]) {
// flag = true;
// break;
// }
// }
// if (flag) {
// arr[i] = (int) (Math.random() * 30) + 1;
// flag = false;
// continue;
// }
// break;
// }
// }
//
// for (int i = 0; i < arr.length; i++) {
// System.out.println(arr[i]);
// }
// 方式二:
int[] arr = new int[6];
for (int i = 0; i < arr.length; i++) {// [0,1) [0,30) [1,31)
arr[i] = (int) (Math.random() * 30) + 1;
for (int j = 0; j < i; j++) {
if (arr[i] == arr[j]) {
i--;
break;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
1.2 从键盘输入一个整数(1~20) ,则以该数字为矩阵的大小,把1,2,3…n*n 的数字按照顺时针螺旋的形式填入其中。
例如: 输入数字2,则程序输出:
1 2
4 3
输入数字3,则程序输出:
1 2 3
8 9 4
7 6 5
输入数字4, 则程序输出:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
class RectangleTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("输入一个数字");
int len = scanner.nextInt();
int[][] arr = new int[len][len];
int s = len * len;
/*
* k = 1:向右 k = 2:向下 k = 3:向左 k = 4:向上
*/
int k = 1;
int i = 0, j = 0;
for (int m = 1; m <= s; m++) {
if (k == 1) {
if (j < len && arr[i][j] == 0) {
arr[i][j++] = m;
} else {
k = 2;
i++;
j--;
m--;
}
} else if (k == 2) {
if (i < len && arr[i][j] == 0) {
arr[i++][j] = m;
} else {
k = 3;
i--;
j--;
m--;
}
} else if (k == 3) {
if (j >= 0 && arr[i][j] == 0) {
arr[i][j--] = m;
} else {
k = 4;
i--;
j++;
m--;
}
} else if (k == 4) {
if (i >= 0 && arr[i][j] == 0) {
arr[i--][j] = m;
} else {
k = 1;
i++;
j++;
m--;
}
}
}
// 遍历
for (int m = 0; m < arr.length; m++) {
for (int n = 0; n < arr[m].length; n++) {
System.out.print(arr[m][n] + "\t");
}
System.out.println();
}
}
}
方法2:
class RectangleTest1 {
public static void main(String[] args) {
int n = 7;
int[][] arr = new int[n][n];
int count = 0; // 要显示的数据
int maxX = n - 1; // x轴的最大下标
int maxY = n - 1; // Y轴的最大下标
int minX = 0; // x轴的最小下标
int minY = 0; // Y轴的最小下标
while (minX <= maxX) {
for (int x = minX; x <= maxX; x++) {
arr[minY][x] = ++count;
}
minY++;
for (int y = minY; y <= maxY; y++) {
arr[y][maxX] = ++count;
}
maxX--;
for (int x = maxX; x >= minX; x--) {
arr[maxY][x] = ++count;
}
maxY--;
for (int y = maxY; y >= minY; y--) {
arr[y][minX] = ++count;
}
minX++;
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
String space = (arr[i][j] + "").length() == 1 ? "0" : "";
System.out.print(space + arr[i][j] + " ");
}
System.out.println();
}
}
}
1.3杨辉三角问题,参见:
Java寒假学习Day5:二维数组简单习题_Dionysus_xu的博客-CSDN博客
2.求数值型数组中元素的最大值、最小值、平均数、总和等
定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,
然后求出所有元素的最大值,最小值,和值,平均值,并输出出来
要求:所有的随机数都是两位数
package Array;
/*
* 2.求数值型数组中元素的最大值、最小值、平均数、总和等
*
* 2.1
* 定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,
要求:所有随机数都是两位数。
然后求出所有元素的最大值,最小值,和值,平均值,并输出出来 。
提示;
随机生成一个两位数
范围:[10,99]
math.random()函数是从0开始的,那么我们只需要利用random函数生成从0~89的数
然后把这个数+10,结果也就是[10,99]
即:Math.random()*(99-10+1)+10
*
*/
public class ArraySF2 {
public static void main(String[] args) {
int[] arr = new int[10];
for(int i=0;i<arr.length;i++) {
arr[i]=(int)(Math.random()*(99-10+1)+10);
}
//遍历数组
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+",");
}
System.out.println();
//最大值
int max=0;
for(int i=0;i<arr.length;i++) {
if(max<arr[i])
max=arr[i];
}
System.out.println("最大值为:"+max);
//最小值
int min=arr[0];
for(int i=0;i<arr.length;i++) {
if(min>arr[i])
min=arr[i];
}
System.out.println("最小值为:"+min);
//总和
int sum =0;
for(int i=0;i<arr.length;i++) {
sum+=arr[i];
}
System.out.println("总和为:"+sum);
//平均数
int average=0;
average+=sum/arr.length;
System.out.println("平均值为:"+average);
}
}
3.数组的复制、反转、查找(线性查找、二分法查找)
3.1数组复制
使用简单数组
(1)创建一个名为ArrayTest的类,在main()方法中声明array1和array2两个变量,
他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值
(如array[0]=0,array[2]=2)。打印出array1。
package Array;
/*
*
* 使用简单数组
(1)创建一个名为ArraySF2_1的类,在main()方法中声明array1和array2两个变量,
他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值
(如array[0]=0,array[2]=2)。打印出array1。
思考:array1和array2是什么关系?
拓展:修改题目,实现array2对array1数组的复制
*/
public class ArraySF2_1 {
public static void main(String[] args) {
//(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
int[] array1 = new int[]{2,3,5,7,11,13,17,19};
//(3)显示array1的内容。
for(int i=0;i<array1.length;i++) {
System.out.print("修改arr2前的array1:"+array1[i]+" ");
}
System.out.println();
//(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值
int[] array2 = array1;
for(int i=0;i<array2.length;i++) {
if(i%2 == 0) {
array2[i]=i;
}
}
//输出arr2的值
for(int i=0;i<array2.length;i++) {
System.out.print(array2[i]+" ");
}
System.out.println();
//修改arr2后再输入一次arr1
for(int i=0;i<array1.length;i++) {
System.out.print("修改arr2后的array1:"+array1[i]+" ");
}
//(Ex)显示array1在堆中的首地址值
System.out.println(array1);
//(Ex)显示array2在堆中的首地址值
System.out.println(array2);
}
}
思考:array1和array2是什么关系?
从最后的首地址位置可以看出,在堆中是同一个数组,只是把arr1的地址赋给了arr2
提升:实现array2对array1数组的复制
package Array;
/*
*
* 使用简单数组
(1)创建一个名为ArraySF2_1的类,在main()方法中声明array1和array2两个变量,
他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值
(如array[0]=0,array[2]=2)。打印出array1。
思考:array1和array2是什么关系?
拓展:修改题目,实现array2对array1数组的复制
*/
public class ArraySF2_2 {
public static void main(String[] args) {
int[] array1 = new int[]{2,3,5,7,11,13,17,19};
System.out.println("arr1为:");
for(int i=0;i<array1.length;i++) {
System.out.print(array1[i]+" ");
}
System.out.println();
int[] array2 = new int[array1.length];
System.out.println("arr2为:");
for(int i=0;i<array1.length;i++) {
array2[i]=array1[i];
System.out.print(array2[i]+" ");
}
System.out.println();
//测试首地址
System.out.println("arr1首地址"+array1);
System.out.println("arr2首地址"+array2);
}
}
3.2数组反转
package Array;
/*
* 数组的反转
*/
public class ArraySF2_3 {
public static void main(String[] args) {
String[] arr = new String[] {"AA","BB","CC","DD","EE","FF","GG"};
//数组复制
String[] arr1 = new String[arr.length];
for(int i = 0; i < arr1.length;i++) {
arr1[i]=arr[i];
}
//数组反转
for(int i=0;i<arr1.length/2;i++) {
String temp = arr1[i];
arr1[i] = arr1[arr1.length-1-i];
arr1[arr1.length-1-i] = temp;
}
System.out.println("反转前");
for(int i =0; i< arr.length;i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
System.out.println("反转后");
for(int i =0; i< arr1.length;i++) {
System.out.print(arr1[i]+" ");
}
System.out.println();
}
}
3.3数组查找
3.3.1线性查找
package Array;
/*
* 数组的查找
* 线性查找
*/
public class ArraySF2_4 {
public static void main(String[] args) {
String[] arr = new String[] { "AA", "BB", "CC", "DD", "EE", "FF", "GG" };
String dest = "BB";
boolean flag = true;
for (int i = 0; i < arr.length; i++) {
if (dest.equals(arr[i])) {
System.out.println("找到了,位置为:" + i);
flag = false;
break;
}
}
if (flag) {
System.out.println("很遗憾,没找到");
}
}
}
3.3.2二分查找
package Array;
/*
* 数组查找,二分法
*
*/
public class ArraySF2_5 {
public static void main(String[] args) {
//二分法
//前提:查找的数组要有序
int arr[] = new int[] {-41,-33,-21,-17,0,14,27,37,46,51};
int dest = -33;
int head = 0;
int end = arr.length-1;
boolean isFlag=true;
while(head<=end) {
int middle = (head+end)/2;
if(dest == arr[middle]) {
System.out.println("找到了!索引为:"+middle);
isFlag = false;
break;
}else if(dest < arr[middle]) {
end = middle - 1;
}
else {
head = middle + 1;
}
}
if(isFlag) {
System.out.println("很抱歉,没找打");
}
}
}
4.数组元素的排序算法
假设含有n个记录的序列为{R1,R2,...,Rn},其相应的关键字序列为{K1,K2,...,Kn}。将这些记录重新排序为{Ri1,Ri2,...,Rin},使得相应的关键字值满足条Ki1<=Ki2<=...<=Kin,这样的一种操作称为排序。
通常来说,排序的目的是快速查找。(二分法要先排序)
4.1排序算法的指标
①时间复杂度:分析关键字的比较次数和记录的移动次数
②空间复杂度:分析排序算法中需要多少辅助内存
③稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排
序算法是稳定的。
4.2排序算法分类
4.2.1内部排序:整个排序过程不需要借助于外部存储器(如磁盘等),所有排序操作都在内存中
完成。
八种常见的内部排序:(红色要求掌握,蓝色要求了解思想
)
①直接选择排序
② 堆排序
③ 冒泡排序
④ 快速排序
⑤ 直接插入排序
⑥折半插入排序
⑦Shell排序
⑧归并排序
4.2.2 外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助于外部存储器(如磁盘)。外部排序最常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。
4.3具体代码实现
4.3.1冒泡排序
package Array;
/*
* 数组排序
* 冒泡排序
*/
public class ArraySF3_1 {
public static void main(String[] args) {
int[] arr = new int[] {-7,41,32,33,62,-40,33,72,108,9,0,-55};
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
//冒泡排序
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;
}
}
}
//排序后输出
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
4.3.2快速排序
package com.atguigu.array.sort;
/**
* 快速排序
* 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,
* 则分别对这两部分继续进行排序,直到整个序列有序。
* @author Dionsys_xu
* 2022-1-18
*/
public class QuickSort {
private static void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
private static void subSort(int[] data, int start, int end) {
if (start < end) {
int base = data[start];
int low = start;
int high = end + 1;
while (true) {
while (low < end && data[++low] - base <= 0)
;
while (high > start && data[--high] - base >= 0)
;
if (low < high) {
swap(data, low, high);
} else {
break;
}
}
swap(data, start, high);
subSort(data, start, high - 1);//递归调用
subSort(data, high + 1, end);
}
}
public static void quickSort(int[] data){
subSort(data,0,data.length-1);
}
public static void main(String[] args) {
int[] data = { 9, -16, 30, 23, -30, -49, 25, 21, 30 };
System.out.println("排序之前:\n" + java.util.Arrays.toString(data));
quickSort(data);
System.out.println("排序之后:\n" + java.util.Arrays.toString(data));
}
}
后续关于算法问题我会在数据结构里仔细讲一遍,包括思想,算法