数组
数组是引用数据类型,用来保存多个数据
特性: 连续存储,下标从0开始,数组一旦创建,长度不能修改. 查询和修改效率极高,添加和删除效率较低(并且数组没有提供添加和删除功能). 数组中有length 属性 保存了数组的长度
静态声明: 数据类型[] 变量名 = {值,值,值....};
动态声明: 数据类型[] 变量名 = new 数据类型[长度];
int[] arr1 = { 1, 2, 3, 4 };
int[] arr2 = new int[10];
//获取数据
System.out.println(arr1[0]);
System.out.println(arr1[3]);
System.out.println(arr1.length);
// 最后一个数据
System.out.println(arr1[arr1.length-1]);
// 遍历
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
常见异常(下标越界):Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
数组合并 (初级)
//JDK自带的数组合并方法
public static void arraycopy
(int[] src, int srcIndex, int[] dest,int destIndex, int length)
// 源数组,源数组起始位置(包含),目标数组,目标数组起始位置(包含),复制个数
{
//是替换
}
实现插入式复制:
public class ArrayInsert {
public static void main(String[] args) {
int[] src = {1, 2, 3, 4, 5};
int[] dest = {11, 12, 13, 14, 15};
dest = arraycopy(src, 1, dest, 1, 3);
for (int i : dest) {
System.out.println(i);
}
}
public static int[] arraycopy(int[] src, int srcIndex, int[] dest, int destIndex, int length) {
int index = 0;
int[] newArray = new int[dest.length + length];
for (; index <= destIndex; index++) {
newArray[index] = dest[index];
}
//index = destIndex + 1
//newArray[] = {11, 12, 0, 0, 0, 0, 0, 0}
//temp[] : src[]:srcIndex ~ srcIndex + length - 1
for (int i = srcIndex; i < srcIndex + length; i++) {
newArray[index] = src[i];
index++;
}
//index = destIndex + 1 + length
//newArray[] = {11, 12, 2, 3, 4, 0, 0, 0}
for (int i = destIndex + 1; i <= dest.length - 1; i++) {
newArray[index] = dest[i];
index++;
}
return newArray;
}
}
二维数组
int[] arr1 = {1, 2, 3};
// 二维数组,保存的都是一维数组
int[][] arr2 = {arr1,arr1};
// 1 静态声明
int[][] arr3 = {
{1,2,3},{4,3,2},{1,5,3,7}
};
// 2 动态声明
// 二维数组中,有3个一维数组,并且每个一维数组中有5个元素
int[][] arr4 = new int[3][5];
例: 杨辉三角
public class _01_YangHuiTriangle {
public static void main(String[] args) {
int[][] arr_triangle = new int[7][];
for (int i = 0; i <= arr_triangle.length - 1; i++) {
arr_triangle[i] = new int[i + 1];
}
for (int i = 0; i <= arr_triangle.length - 1; i++) {
System.out.println();
for (int j = 0; j <= i; j++) {
if (j == 0 || j == arr_triangle[i].length - 1) {
arr_triangle[i][j] = 1;
} else
arr_triangle[i][j] = arr_triangle[i - 1][j - 1] + arr_triangle[i - 1][j];
System.out.print(arr_triangle[i][j] + "\t");
}
}
}
}
排序
两个经典排序算法:
冒泡排序
比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对, 最后的元素应该会是最大的数。针对所有的元素重复以上的步骤,除了最后一个. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
public class _01_BubbleSort {
public static void main(String[] args) {
int[] arr = { 2, 6, 8, 12, 9, 5, 16, 7, 23, 7, 4, 10 };
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]) {
arr[j] = arr[j] ^ arr[j + 1];
arr[j + 1] = arr[j] ^ arr[j + 1];
arr[j] = arr[j] ^ arr[j + 1];
}
}
}
for (int i : arr) {
System.out.println(i);
}
}
}
选择排序
每次把最小的放到左边. 拿出第一个,假设是最小的,然后挨个和后面的比较,如果有比第一个小的,就交换下标当比较完一轮之后,已经得到了最小元素的下标,然后放到最前面进行换位即可2 重复执行这个步骤,直到当前元素后面 没有其他元素的时候终止
public class _02_SelectionSort {
public static void main(String[] args) {
int[] arr = { 2, 6, 8, 12, 9, 5, 16, 23, 7, 7, 4, 10 };
int minIndex;
for (int i = 0; i < arr.length - 1; i++) {
minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j;
}
}
if (minIndex != i) {
arr[i] = arr[minIndex] ^ arr[i];
arr[minIndex] = arr[minIndex] ^ arr[i];
arr[i] = arr[minIndex] ^ arr[i];
}
}
for (int i : arr) {
System.out.println(i);
}
}
}
查找
顺序查找
用数组的每一个数据,挨个和目标数据进行比较,找到则返回索引,如果比较完没有找到,则返回-1
优点 : 编码简单,如果要查找的元素在数组中位置靠前的话,找到的比较快
缺点 : 一旦数据多了之后,挨个比较,效率相对不稳定,比如 目标数据相对靠后的时候,或者是不存在时,效率较低
public static int doSequentialSearch(int target) {
int i = 0;
while (i < arr.length) {
if (target == arr[i]) {
return i;
}
i++;
}
return -1;
}
二分查找
又称为折半查询,每次都和中间数据进行比较. 目标数据大于中间数据,结束索引不变,起始索引=中间索引+1,再生成中间索引 .目标数据小于中间数据,起始索引不变,结束索引=中间索引-1,再生成中间索引. 当起始索引,大于结束索引时,终止,说明不存在该数据
优点 : 因为每次筛选一半,所以效率比较高,尽管数据靠前或者靠后,查询性能都比较均衡
缺点 : 必须建立在已排序的基础之上
public static int doBinarySearch(int[] arr, int target) {
int leftIndex = 0;
int rightIndex = arr.length - 1;
int midIndex = (leftIndex + rightIndex) / 2;
while (leftIndex <= rightIndex) {
if (target > midIndex) {
leftIndex = midIndex + 1;
} else if (target < midIndex) {
rightIndex = midIndex - 1;
} else {
return midIndex;
}
midIndex = (leftIndex + rightIndex) / 2;
}
return -1;
}