这系列博文主要是将自己之前学习的一些java基础内容进行归纳与总结。
数组可以存储多个相同类型的数据并对其从0开始编号,通过编号(索引)完成对元素的操作。
数组一旦定义,所占用的内存空间就固定了,所以数组不可变。
一维数组定义方式有三种,二三种写法比较常见。
// (一)静态初始化
int[] arr = new int[]{1,2,3};
// (二)静态初始化
int[] arr1 = {1,2,3};
// (三)动态初始化
int[] arr2 = new int[3];
// 对于动态初始化,只是确定容量,无法判断实际存储了多少元素
System.out.println(arr2.length);
// 遍历
for (Integer val : arr) {
System.out.print(val);
}
// 使用工具类快捷打印
System.out.println(Arrays.toString(arr));
数组嵌套数组,二三种写法比较常见
// (一)静态初始化
int[][] arrs = new int[][]{{1}, {2, 3}, {4, 5, 6}};
// (二)静态初始化
int[][] arrs1 = {{}, {}, {}};
// (三)动态初始化
int[][] arrs2 = new int[2][3];
// (四)动态初始化 也可只定义第一维度的容量
int[][] arrs3 = new int[3][];
System.out.println(arrs.length); // 第一维度的容量
// 遍历
for (int[] arr : arrs) {
for (Integer val : arr) {
System.out.print(val);
}
}
// 使用工具类快捷打印
System.out.println(Arrays.deepToString(arrs));
二维数组其实就是一个矩阵,对于动态初始化来说new int[][]
第一个[]
代表着这个二维数组中有多少个一维数组,第二个[]代表着一维数组的容量,并且第一个[]
不能为空
当然也可以定义个N维数组[狗头]
int[][][][][] i = new int[2][2][2][2][2];
System.out.println(Arrays.deepToString(i));
一些比较奇怪的写法
int x []; // 不推荐
int x1 [][]; // 不推荐
int [] x2 []; // 会被打
int[] x3, y[]; // x3是一维数组,y是二维数组
两两相邻元素进行排序,将最大(最小)的放置最后
时间复杂度O(N^2)
第一次内循环比较n - 1次,然后是n-2次,n-3次,……,最后一次内循环比较1次。
等差数列求和
( ( n − 1 ) + 1 ) ( n − 1 ) / 2 = n ( n − 1 ) / 2 ((n-1)+1)(n-1)/2=n(n-1)/2 ((n−1)+1)(n−1)/2=n(n−1)/2
Big O表示法:只保留最高项,并且去除最高项常数
最终推导为 O(N^2)
private static void bubbleSort(int[] arr){
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;
}
}
}
}
将第i位数与其后的所有数做比较,当遇到小于(大于)的就将其角标存储,每一轮结束如果角标有变动则进行交换,第i个数就是最小(最大)的
时间复杂度O(N^2)
第一次内循环比较n - 1次,然后是n-2次,n-3次,……,最后一次内循环比较1次。
求等差数列和
( ( n − 1 ) + 1 ) ( n − 1 ) / 2 = n ( n − 1 ) / 2 ((n-1)+1)(n-1)/2=n(n-1)/2 ((n−1)+1)(n−1)/2=n(n−1)/2
最终推导为 O(N^2)
private static void selectSort(int[] arr){
for (int i = 0; i < arr.length - 1; i++) {
int index = i;
for (int j = i+1; j < arr.length; j++) {
if (arr[index] > arr[j]) {
index = j;
}
}
if (index != i) {
int temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
}
}
}
时间复杂度O(NLogN)
指针交换法
private static void quickSort(int[] arr, int left, int right){
if(left >= right){
return;
}
// 左哨兵i, 右哨兵j, 基准数pivot
int i = left, j = right, pivot = arr[i];
// 这里必须j先动,否则ij相遇时的元素必定大于基准数,因为i是遇到大于基准数的才停止
while(i < j){
// j先动遇到小于等于基准数的就停止
while (arr[j] >= pivot && i < j) {
j--;
}
// i后动遇到大于等于基准数的就停止
while (arr[i] <= pivot && i < j){
i++;
}
// 交换两个指针元素
if(i < j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// 第一轮循环好后就能确定重合点,将基数与重合点元素交换
arr[left] = arr[i];
arr[i] = pivot;
// 递归调用左边
quickSort(arr, left, i - 1);
// 递归调用右边
quickSort(arr, i + 1, right);
}
private static int binarySearch(int[] arr, int key){
int min = 0, mid, max = arr.length-1;
while(min <= max){
mid = (min + max)/2;
if(key > arr[mid]){
min = mid + 1;
}else if(key < arr[mid]){
max = mid - 1;
}else {
return mid;
}
}
return -1;
}