随便记一记数组相关的经典练习题吧,首先要掌握两个数交换的方法(两条平行线 //,上一行的最后一个变量是下一行的第一个变量,很好记)。
temp = a;
a = b;
b = temp;
1.赋值练习–杨辉三角
首先要知道杨辉三角长什么样子,如下:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
有什么用?搜索引擎搜一下就知道了,都是古人智慧的结晶呀!
定义:
行首行末都为1,第 i 行 j 列的数等于,i-1 行 j 列 与 i-1 行 j-1 列之和。
思路:
首先看考察的什么问题–数组的赋值。在赋值的时候可以分步骤来
1.先直接赋值 首末元素 = 1;
2.再是带入公式赋值 非首末 元素
public class Test {
public static void main(String[] args) {
// 1.声明并初始化二维数组
int[][] yangHui = new int[10][];
// 2.给数组元素赋值
for (int i = 0; i < yangHui.length; i++) {
yangHui[i] = new int[i + 1];
// 2.1给数组首末的元素赋值
yangHui[i][0] = yangHui[i][i] = 1;
// 2.2给数组的非首末元素赋值,注意赋值从第3行开始,i=2.
if (i > 1) {//这个if不要也罢
for (int j = 1; j < yangHui[i].length - 1; j++){
yangHui[i][j] = yangHui[i - 1][j - 1] + yangHui[i - 1][j];
}
}
}
// 3.遍历二维数组
for (int i = 0; i < yangHui.length; i++) {
for (int j = 0; j < yangHui[i].length; j++) {
System.out.print(yangHui[i][j] + " ");
}
System.out.println();
}
}
}
注意:
1. 在给非首末元素赋值的时候要注意,j 的起点是1没毛病,但 j 的终点要考虑一下了,因为yangHui[i][j] = yangHui[i - 1][j - 1] + yangHui[i - 1][j];要保证下标不能越界,可以在写终止条件的时候举个5行的例子推敲一下,数组计数仍从0开始。yangHui[4].length = 5,j < 5-1,则 j 能取到3,yangHui[4][3]就是第五行末尾前面一个数。
2. 其实if不要也罢,当i=0,length=1,1-1=0,无法进入下面的for循环,i=1同理,自然就屏蔽掉杨辉三角的前两行。
2.一维数组反转
思路:
1.只使用一个条件控制循环,只需要保证头和尾加起来的索引 = length - 1,循环只需要进行 length / 2 次;
2.使用两个条件控制循环,一头一尾,不满足 i < j 循环终止
public class Test {
public static void main(String[] args) {
int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };
// 方法一
for (int i = 0; i < arr.length / 2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length - i - 1];
// 头和尾加起来的索引=length-1
arr[arr.length - i - 1] = temp;
}
//方法二
for (int i = 0,j = arr.length - 1; i < j; i++,j--) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 遍历
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
3.一维数组查找
思路:
基础类型判断相不相等就完事儿了,String等引用类型用equals方法(自定义引用类型需要自己重写)
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要查找的数:");
int sereach = scanner.nextInt();
int[] arr = new int[] {1,2,3,4,5,6};
boolean isFlag = true;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == sereach) {
System.out.println("找到了,位置为:" + i);
isFlag = false;
break;
}
}
if (isFlag) {
System.out.println("没找到哦!");
}
}
}
4.冒泡排序
初学可能比较难,有数据结构基础的可以看看
思路:
嵌套for循环,外层控制轮次(趟数),内层交换数据,前后依次比较,要注意上一轮最大的数字及以后不参与交换。
public class Test {
public static void main(String[] args) {
int[] arr = new int[] { 3, 4, 3, 7, 6, 5 };
for (int i = 0; i < arr.length - 1; i++) {
//控制轮次0.1.2.3.4共五轮
for (int j = 0; j < arr.length - 1 - i; j++) {
//数据交换,并且上一轮最大的数字及以后,不参与交换
//例第0轮,i=0,arr.length-1-i=5,j<5,则最大j=4,
//arr[j+1]能取到索引为5的数(最后一个数)
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] + "\t");
}
}
}
//输出结果为:3 3 4 5 6 7
5.快速排序(看了数据结构再来)
这里只做算法记录,方便日后查阅,算法的思想不深度剖析,真要了解的话,网上很多大神的帖子或视频很不错的。
算法思想:
选数组中的一个数(一般选第一个),用start和end做数组下标,用于交换数据。每一趟将一个数组分为两个数组,前段数组都比这个数小,后段数组都比这个数大,再对这两个数组递归调用快排。
public class Test {
//交换方法
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;
}
}
//low和high交叉了,这时data[start]>data[high],交换
swap(data, start, high);
subSort(data, start, high - 1);// 递归调用前半段数组,都小于data[high]
subSort(data, high + 1, end);// 递归调用前半段数组,都大于data[high]
}
}
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));
}
}