百知教育学习 - 胡鑫喆 - 数组
一、数组的认识
二、数组创建语法
-
先声明、再分配空间:
数组类型[] 数组名;
数组名 = new 数据类型[长度] -
声明并分配空间:
数据类型[] 数组名 = new 数据类型[长度] -
声明并赋值(繁)
数据类型[] 数组名 = new 数据类型[]{
value 1, value 2, value 3, …}
三、可变长参数
public static int add(int... a){ //其中a是可变长参数,调用的时候可以传任意多个参数
int result = 0;
for(int i = 0; i <a.length; i++){
result += a[i];
}
return result;
}
四、数组存储特点
- 由于数组存储 地址是连续的,因此数组的长度无法改变。
- 要想对数组进行扩充,只能再定义一个更大的数组,同时把之前数组中的值赋值到后一数组中。
五、数组的优缺点
-
数据类型的值
基本数据类型(8种)其中存储的是变量的值,对象数据类型——其中存储的是变量的首地址 -
数组的优点:
是一个查询效率很高的数据结构,因为空间连续。 -
数组的缺点:
插入和删除效率低 -
链表与散列表
链表与数组的优缺点正好 相反,而散列表同时具有数组和链表的 优点。
六、二维数组
-
概念:
一维数组中的一维数组;数组中的 元素还是数组。(java中二维数组不存在) -
注意:
二维数组是不连续的,只有一维数组中的一维数组是连续的。 -
创建语法:
- 数据类型 [][] 数组名 = new 数据类型[高维长度][低维长度];
- ** 数据类型 [][] 数组名 = new 数据类型[高维长度][];//接着再给低维分配空间(长度可以不同)
-
实例(杨辉三角)
package day5;
import java.util.*;
public class Exc4_1{
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("请输入一个整数:");
int n = s.nextInt();
int[][] a = new int[n][];
for(int i = 0; i < n; i++) {
a[i] = new int[i+2];
a[i][0] = 1;
a[i][i+1] = 1;
for(int j = 1; j < i+1; j++) {
a[i][j] = a[i-1][j-1]+a[i-1][j];
}
for(int j = 0; j < n-i; j++) {
System.out.print(" ");
}
for(int j = 0; j < i+2; j++) {
System.out.printf("%2d ",a[i][j]);
}
System.out.println();
}
}
}
八、排序和搜索算法
-
排序算法
-
冒泡排序:(核心:相邻两个元素比较大小、交换位置)
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; } } }
-
选择排序:(核心:一个元素和其他所有元素比较)
for(int i = 0 ; i < a.length-1; i++){ for(int j = i+1; j < a.length; j++){ if(a[i] > a[j]){ int temp = a[i]; a[i] = a[j]; a[j] = temp; } } }
-
JDK排序:
import java.util.Arrays.sort(a); -
桶排序:
- 应用场景: 数组元素的**上限较小,而且是整数**。
- 特点: 相对于冒泡和选择排序是以 空间换时间 的做法。
- 核心代码:
int[] b = new int[a元素的最大值+1] for(int i = 0; i < a.length; i++){ b[a[i]]++; } for(int i = 0; i < b.length; i++){ for(int j = 1; j <= b[i]; j++){ System.out.print(i+"\t"); } }
- 用到的知识: 投票算法和自然排序
-
快速排序:
- 思想: 分组、递归
- 理解方法: 先找出 基准值 将数组元素分成两国人,两端元素为两国的哨兵,哨兵发现别国的人就扔回去直到两者相遇(基准值的位置)。
- 核心代码:
static void sort(int[] a, int start ,int end) { if(start >= end) return; int i = start; int j = end; int value = a[start]; while(i < j) { while(i < j && a[j] >= value) j--; if(i < j) { a[i] = a[j]; i++; } while(i < j && a[i] <= value) i++; if(i < j) { a[j] = a[i]; j--; } } a[i] = value; //接着分治递归给基准值两边的元素排序 //排序 a数组 start到i-1的范围 sort(a, start, i-1); //排序 a数组 j+1到end的范围 sort(a, j+1, end);
-
-
搜索算法
- 二分查找法:(核心:元素都已按大小顺序排列,每一次都将要查找的数跟中间的数进行比较,每次缩小一半查找范围。)
package day6; import java.util.*; public class TestSearch{ public static void main(String[] args) { int[] a = new int[5]; Scanner s = new Scanner(System.in); System.out.println("请输入一个含有五个元素且按升序排列的一维数组:"); for(int i = 0; i < 5; i++) { a[i] = s.nextInt(); } System.out.print("请输入要查找的数:"); int n = s.nextInt(); if(search(a, n, 0, a.length-1) == -1) { System.out.println("没找到要查找的数!"); } else System.out.println("要查找的数的下标为: "+search(a, n, 0, a.length-1)); } public static int search(int[] a, int n, int start, int end) { int middle = (start+end)/2; if(start > end) return -1; if(a[middle] > n) { return search(a, n, start, middle-1); } else if(a[middle] < n) { return search(a, n, middle+1, end); } else return middle; } }
- 顺序查找法
- 分治思想: 把大问题化解为小问题的方法叫做 分治,而当小问题的 解决方法 与大问题 相同 时就可用 递归。
- 二分查找法:(核心:元素都已按大小顺序排列,每一次都将要查找的数跟中间的数进行比较,每次缩小一半查找范围。)
九、异或
-
实例:
- 找出一个数组中成单的元素,其余元素都成对出现。
- 代码
package day7; public class Exc1{ public static void main(String[] args) { int[] a = {2, 1, 5, 4, 5, 7, 1, 2, 4}; /* 比较复杂的方法 java.util.Arrays.sort(a); boolean flag = false; for(int i = 0; i < a.length-1; i += 2) { if(a[i] != a[i+1]) { System.out.println(a[i]); flag = true; break; } } if(!flag) System.out.println(a[a.length-1]); */ int result = 0; for(int i = 0; i < a.length; i++) { result ^= a[i]; } System.out.println(result); } }
-
用法:
0异或 任何数结果都是 它本身,不同数异或为1,相同为0
十、实例(八个皇后)
-
思想:
分治、递归,搜索算法—深度优先搜索
-
理解方法:
首先,明白一行只能放一个皇后,从而只需把每一行的皇后放好,再使用递归。具体实现: 穷举 出在某一行中皇后的所有放法,再分析某一列放皇后的话是否和前面几行的皇后冲突,如果冲突就把皇后放到下一列,如果不冲突就放下一行的皇后。
-
核心代码:
//计算第row行的皇后放在第几列 a[row]=? static void place(int[] a, int row) { if(row == a.length) { for(int i = 0; i < a.length; i++) { System.out.print(a[i]+" "); } System.out.println(); return; } outer:for(a[row] = 0; a[row] < a.length; a[row]++) { //判断a[row] 和 前面的row行是不是冲突 for(int i = 0; i < row; i++) { //判断a[row] 和 a[i] 是不是冲突 if(a[row]==a[i] || a[row]-a[i]==row-i || a[row]-a [i]==i-row) { continue outer; } } //放下一行 place(a, row+1); } }