Java二维数组和排序算法

文章目录

  • 二维数组
    • Scanner
    • 案例 : 计算器
  • 排序算法
    • 变量交换
    • 排序
      • 冒泡排序
      • 选择排序
    • 查找
      • 二分法

二维数组

我们可以使用数组保存多个数据

比如我们这个教室,坐着的都是大数据14期的学生,这个教室就相当于数组,我们就是数组中的元素
但是隔壁还有一个前端07期,里面都是07期的学生,
这两个教室都在1808,如果把07和14当成数组的话,1808就是二维数组

二维数组本质 就是一个平面数据结构(表)
二维数组中的元素都是一维数组

Scanner

接收控制台输入

public class Array_03 {

	public static void main(String[] args) {
		// 创建一个接收器
		Scanner sc = new Scanner(System.in);

		// 程序执行到这里的时候就不执行了
		// 等待用户输入 并敲回车结束
		// next : 读取一个数据 多个数据使用 空格隔开
		// String userInput = sc.next();

		// 读取一行数据
		// String userInput = sc.nextLine();

		// 接收int值 nextInt : 分隔符是空格,只接收一个数据
		// 必须是纯数字才可以,小数点也不能有
		// int userInput = sc.nextInt();

		// 读取小数,同上,只是可以有小数点
		double userInput = sc.nextDouble();
		System.out.println(userInput);
	}
}

案例 : 计算器

使用Scanner 完成计算器功能
只需要实现 加减乘除取余即可

      • / %

只需要考虑两个数 比如 1+2 或者 3*2 这种

思路 :
根据题目得知,我们需要接收三个参数 , 比如 1+2 需要把 1 和 + 和 2 都获取

  1. 创建接收器Scanner
  2. 接收 三个参数
  3. 判断第二个参数(运算符) , 如果是 + 就相加,如果是- 就相减…
  4. 如果是 / 需要判断,除数不能为0
import java.util.Scanner;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

/**
 * 使用Scanner完成计算器功能,只需要实现,加减乘除取余即可 + - * / %
 * 
 * 只需要考虑两个数 比如 1+2 或者 3*2 这种
 * 
 * 思路 : 根据题目得知,我们需要接收三个参数 , 比如 1+2 需要把 1 和 + 和 2 都获取 1 创建接收器Scanner 2 接收 三个参数 3
 * 判断第二个参数(运算符) , 如果是 + 就相加,如果是- 就相减... 4 如果是 / 需要判断,除数不能为0
 * 
 * @author lenovo
 * @Date 2020年7月1日
 * @Time 下午9:25:27
 */
public class Array_04 {

	public static void main(String[] args) throws ScriptException {
		// TODO Auto-generated method stub
		// m1();
		test();
	}

	public static void m1() {

		System.out.println("请输入 : n +-*/ m");

		// 创建接收器Scanner
		Scanner sc = new Scanner(System.in);

		// 接收 三个参数
		double number1 = sc.nextDouble();
		String number2 = sc.next();
		double number3 = sc.nextDouble();

		switch (number2) {
		case "+":
			System.out.println(number1 + number3);
			break;
		case "-":
			System.out.println(number1 - number3);
			break;
		case "*":
			System.out.println(number1 * number3);
			break;
		case "/":

			// 如果是 / 需要判断,除数不能为0
			if (number3 == 0) {
				System.out.println("除数不能为0");
				return;
			}

			System.out.println(number1 / number3);
			break;
		case "%":
			System.out.println(number1 % number3);
			break;
		default:
			System.out.println("暂不支持该运算符");
			break;
		}

	}

	public static void test() throws ScriptException {
		// JDK自带的类可以实现调用JS的功能,可以实现执行字符串中的运算公式
		ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
		// 接收控制台输入
		Scanner sc = new Scanner(System.in);
		// 读取一行数据
		String strs = sc.nextLine();
		// 运算结果
		int result = (int) jse.eval(strs);
		System.out.println(result);
	}
}

排序算法

变量交换

交换两个变量的值

public class Array_05 {

	public static void main(String[] args) {
		/**
		 * 第一种 : 中间变量(开发常用)
		 */
		int x = 10;
		int y = 20;
		int temp = x;
		x = y;
		y = temp;
		System.out.println("x=" + x);
		System.out.println("y=" + y);

		/**
		 * 第二种 : 位移运算交换(面试常用)
		 * 
		 * 先把a和b转换为对应的二进制,然后 用 a和b的每一位二进制 进行比较,如果相等,就是0,不一样就是 1
		 */

		int a = 2;
		int b = 3;
		b = a ^ b;
		a = a ^ b;
		b = a ^ b;
		System.out.println("a=" + a);
		System.out.println("b=" + b);

		/**
		 * 3 加和运算
		 */

		int c = 10;
		int d = 20;
		c = c + d;
		d = c - d;
		c = c - d;
	}
}

排序

很多情况下都需要对数据的大小进行排序,比如统计成绩,查询前三名
就需要按照成绩进行降序,然后取 0,1,2即可

冒泡排序

  1. 比较相邻的两个元素,如果第一个比第二大就交换位置
  2. 对每一对相邻的元素做相同的工作,从第一对一直比较到最后一对,比较一轮结束后,最后一个元素一定是最大的
  3. 针对所有元素,重复上面的步骤,除了最后一个元素
  4. 持续循环中,比较次数越来越少,一直剩下一个数据(没有一对了,只有一个了),比较结束

实现 :

  1. 嵌套循环,因为循环一次只能查询出一个最大或者最小
  2. 因为每次循环之后,最后一个不需要比较,所以每次循环,循环的次数都会减一,所以内层循环的循环次数取决于外层
  3. 需要一个临时变量交换数据
public class Array_06 {

	public static void main(String[] args) {
		int[] a = { 3, 2, 4, 5, 1 };
		bubbleSort(a);
		for (int i : a) {
			System.out.println(i);
		}
		// 1 2 3 4 5
	}

	public static void bubbleSort(int[] a) {

		// 外层循环决定循环次数(共比较几轮)
		for (int i = 0; i < a.length - 1; i++) {

			// 内层循环决定每一次循环的循环次数
			for (int j = 0; j < a.length - 1 - i; j++) {

				// 如果是降序 就换成 < 即可
				if (a[j] > a[j + 1]) {
					int temp = a[j];
					a[j] = a[j + 1];
					a[j + 1] = temp;
				}
			}
		}
	}
}

选择排序

  1. 每次都把当中最小的放到最左边
  2. 先拿出第一个元素,假设这个元素是最小的元素,然后挨个和后面所有比较,全部比较完之后,如果有比第一个小的,就交换位置,把这个最小的放到第一位
  3. 交换需要临时变量

实现 :

public class Array_07 {

	public static void main(String[] args) {
		int[] arr = { 1, 3, 4, 5, 2 };
		selectSort(arr);
		// m1(arr);
		for (int i : arr) {
			System.out.println(i);
		}
	}

	public static void m1(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr.length; j++) {
				if (arr[i] > arr[j]) {
					int tmp = arr[i];
					arr[i] = arr[j];
					arr[j] = tmp;
				}
			}
		}
	}

	public static void selectSort(int[] arr) {
		// 从小到大排序
		for (int i = 0; i < arr.length - 1; i++) {
			// 最小元素的下标,默认是第一个元素
			int min = i;
			for (int j = i + 1; j < arr.length; j++) {
				// 如果 min 大于 j 说明 i 不是最小的元素
				// 就交换下标
				if (arr[min] > arr[j]) {
					min = j;
				}
			}
			// 如果min不等于 i 说明最小值不是 i 需要换位
			if (min != i) {
				int temp = arr[i];
				arr[i] = arr[min];
				arr[min] = temp;
			}
		}
	}
}

查找

二分法

当数据过大的时候,想要查找某个数据,并不是一件容易的事,尤其是我们要找的数据可能在最后几条,如果依次比较数据,效率太低

  1. 必须建立在已经排序的基础之上
  2. 没有重复数据

算法实现 :

  1. 确定数据的开始位置和结束位置
  2. 确定数据的中间位置,判断中间位置元素是否是目标数据,如果是,就直接返回中间数据对应的下标
    3.如果不是,分为两种
  1. 目标数据大于中间数据 起始值 = 中间值 + 1 , 结束值不变
  2. 目标数据小于中间数据
    结束值 = 中间值 -1 , 起始值不变
  1. 更改起始值或结束值之后,必须重新计算中间值

  2. 终止条件 : 当起始值大于结束值的时候,说明没有这个目标数据

Java二维数组和排序算法_第1张图片

public class Array_08 {

	public static void main(String[] args) {
//		int[] arr = { 1, 3, 4, 5, 6, 7, 9, 15, 17, 19, 38, 41, 52, 63, 73, 78 };

		int[] arr = new int[21111111];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = i;
		}
		int num = 20011112;
		long startTime = System.currentTimeMillis();
		int index = search(arr, num);
		System.out.println(num + " 在arr数组的第 : " + index + " 位上,执行了 " + count_1 + " 次");
		long endTime = System.currentTimeMillis();
		System.out.println("传统查找使用 : " + (endTime - startTime) + " 毫秒");

		startTime = System.currentTimeMillis();
		index = binarySearch(arr, num);
		System.out.println(num + " 在arr数组的第 : " + index + " 位上,执行了 " + count_2 + " 次");
		endTime = System.currentTimeMillis();
		System.out.println("二分法查找使用 : " + (endTime - startTime) + " 毫秒");
	}

	// 传统查询次数
	static int count_1 = 0;
	// 二分法查询次数
	static int count_2 = 0;

	/**
	 * 传统写法
	 * 
	 * @param arr
	 * @param num
	 * @return
	 */
	public static int search(int[] arr, int num) {
		for (int i = 0; i < arr.length; i++) {
			count_1++;
			if (arr[i] == num) {
				return i;
			}
		}
		// 能到这里说明没有找到,返回 -1
		return -1;
	}

	/**
	 * 二分法查询
	 * 
	 * @param arr
	 * @param num
	 * @return
	 */
	public static int binarySearch(int[] arr, int num) {
		if (arr == null || arr.length == 0) {
			return -1;
		}
		// 1 确定数据的开始位置和结束位置
		int startPos = 0;
		int endPos = arr.length - 1;
		// 2 确定数据的中间位置,判断中间位置元素是否是目标数据,如果是,就直接返回中间数据对应的下标
		int m = (startPos + endPos) / 2;
		// 终止条件 : 当起始值大于结束值的时候,说明没有这个目标数据
		while (startPos <= endPos) {
			count_2++;
			if (num == arr[m]) {
				return m;
			}
			// 3 如果不是,分为两种
			// 1 目标数据大于中间数据
			// 起始值 = 中间值 + 1 , 结束值不变
			if (num > arr[m]) {
				startPos = m + 1;
			}
			// 2 目标数据小于中间数据
			// 结束值 = 中间值 - 1 , 起始值不变
			if (num < arr[m]) {
				endPos = m - 1;
			}
			m = (startPos + endPos) / 2;
		}

		// 能到这里 说明没有找到,直接返回-1
		return -1;
	}
}

你可能感兴趣的:(#,数组,java)