左神基础班第一课
之前一直在犹豫ACM,要不要走下去,一些课程也没有成体系,东一榔头,西一棒槌。加油吧,学到的技术就是自己的。
左神首先讲了时间复杂度的概念,很通俗易懂,
简单来说,就是看变化的趋势幅度,突出主要因素,忽略次要因素。
接下来,便是冒泡排序,代码如下。
- package basic_class_01;
- import java.util.Arrays;
- public class Code_00_BubbleSort {
- public static void bubbleSort(int[] arr) {
- if (arr == null || arr.length < 2) {
- return;
- }
- for (int e = arr.length - 1; e > 0; e--) {
- for (int i = 0; i < e; i++) {
- if (arr[i] > arr[i + 1]) {
- swap(arr, i, i + 1);
- }
- }
- }
- }
- public static void swap(int[] arr, int i, int j) {
- arr[i] = arr[i] ^ arr[j];
- arr[j] = arr[i] ^ arr[j];
- arr[i] = arr[i] ^ arr[j];
- }
- // for test
- public static void comparator(int[] arr) {
- Arrays.sort(arr);
- }
- // for test
- public static int[] generateRandomArray(int maxSize, int maxValue) {
- int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
- for (int i = 0; i < arr.length; i++) {
- arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
- }
- return arr;
- }
- // for test
- public static int[] copyArray(int[] arr) {
- if (arr == null) {
- return null;
- }
- int[] res = new int[arr.length];
- for (int i = 0; i < arr.length; i++) {
- res[i] = arr[i];
- }
- return res;
- }
- // for test
- public static boolean isEqual(int[] arr1, int[] arr2) {
- if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
- return false;
- }
- if (arr1 == null && arr2 == null) {
- return true;
- }
- if (arr1.length != arr2.length) {
- return false;
- }
- for (int i = 0; i < arr1.length; i++) {
- if (arr1[i] != arr2[i]) {
- return false;
- }
- }
- return true;
- }
- // for test
- public static void printArray(int[] arr) {
- if (arr == null) {
- return;
- }
- for (int i = 0; i < arr.length; i++) {
- System.out.print(arr[i] + " ");
- }
- System.out.println();
- }
- // for test
- public static void main(String[] args) {
- int testTime = 500000;
- int maxSize = 100;
- int maxValue = 100;
- boolean succeed = true;
- for (int i = 0; i < testTime; i++) {
- int[] arr1 = generateRandomArray(maxSize, maxValue);
- int[] arr2 = copyArray(arr1);
- bubbleSort(arr1);
- comparator(arr2);
- if (!isEqual(arr1, arr2)) {
- succeed = false;
- break;
- }
- }
- System.out.println(succeed ? "Nice!" : "Fucking fucked!");
- int[] arr = generateRandomArray(maxSize, maxValue);
- printArray(arr);
- bubbleSort(arr);
- printArray(arr);
- }
- }
冒泡排序的复杂度是O(N^2),分析是 0--n-1 , 0--n-2, 0---n-3,........根据等差数列公式,可得,根据复杂度分析方式。
下面是选择排序
- package basic_class_01;
- import java.util.Arrays;
- public class Code_02_SelectionSort {
- public static void selectionSort(int[] arr) {
- if (arr == null || arr.length < 2) {
- return;
- }
- for (int i = 0; i < arr.length - 1; i++) {
- int minIndex = i;
- for (int j = i + 1; j < arr.length; j++) {
- minIndex = arr[j] < arr[minIndex] ? j : minIndex;
- }
- swap(arr, i, minIndex);
- }
- }
- public static void swap(int[] arr, int i, int j) {
- int tmp = arr[i];
- arr[i] = arr[j];
- arr[j] = tmp;
- }
- // for test
- public static void comparator(int[] arr) {
- Arrays.sort(arr);
- }
- // for test
- public static int[] generateRandomArray(int maxSize, int maxValue) {
- int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
- for (int i = 0; i < arr.length; i++) {
- arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
- }
- return arr;
- }
- // for test
- public static int[] copyArray(int[] arr) {
- if (arr == null) {
- return null;
- }
- int[] res = new int[arr.length];
- for (int i = 0; i < arr.length; i++) {
- res[i] = arr[i];
- }
- return res;
- }
- // for test
- public static boolean isEqual(int[] arr1, int[] arr2) {
- if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
- return false;
- }
- if (arr1 == null && arr2 == null) {
- return true;
- }
- if (arr1.length != arr2.length) {
- return false;
- }
- for (int i = 0; i < arr1.length; i++) {
- if (arr1[i] != arr2[i]) {
- return false;
- }
- }
- return true;
- }
- // for test
- public static void printArray(int[] arr) {
- if (arr == null) {
- return;
- }
- for (int i = 0; i < arr.length; i++) {
- System.out.print(arr[i] + " ");
- }
- System.out.println();
- }
- // for test
- public static void main(String[] args) {
- int testTime = 500000;
- int maxSize = 100;
- int maxValue = 100;
- boolean succeed = true;
- for (int i = 0; i < testTime; i++) {
- int[] arr1 = generateRandomArray(maxSize, maxValue);
- int[] arr2 = copyArray(arr1);
- selectionSort(arr1);
- comparator(arr2);
- if (!isEqual(arr1, arr2)) {
- succeed = false;
- printArray(arr1);
- printArray(arr2);
- break;
- }
- }
- System.out.println(succeed ? "Nice!" : "Fucking fucked!");
- int[] arr = generateRandomArray(maxSize, maxValue);
- printArray(arr);
- selectionSort(arr);
- printArray(arr);
- }
- }
选择排序和冒泡排序类似 时间复杂度都是O(N^2),不做过多分析 。
最后是插入排序,冒泡排序的升级版。
package basic_class_01;
import java.util.Arrays;
public class Code_01_InsertionSort {
public static void insertionSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 1; i < arr.length; i++) {
for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
swap(arr, j, j + 1);
}
}
}public static void swap(int[] arr, int i, int j) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}// for test
public static void comparator(int[] arr) {
Arrays.sort(arr);
}// for test
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
return arr;
}// for test
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}// for test
public static boolean isEqual(int[] arr1, int[] arr2) {
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
return false;
}
if (arr1 == null && arr2 == null) {
return true;
}
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}// for test
public static void printArray(int[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}// for test
public static void main(String[] args) {
int testTime = 500000;
int maxSize = 100;
int maxValue = 100;
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
int[] arr2 = copyArray(arr1);
insertionSort(arr1);
comparator(arr2);
if (!isEqual(arr1, arr2)) {
succeed = false;
break;
}
}
System.out.println(succeed ? "Nice!" : "Fucking fucked!");int[] arr = generateRandomArray(maxSize, maxValue);
printArray(arr);
insertionSort(arr);
printArray(arr);
}}
插入排序很有意思,对于一组数,进行比较,如果后一个数比前一个数小那么就交换,并且和前一个数之前的数进行比较,一直往前比较,直到当前的数比前一个数大。
插入排序的时间复杂度是和数据状况是有关系的,存在最好情况和最差情况,还有平均情况。平常情况下,一律按最差情况估计。所以插入排序是O(N^2).
下面是对数器。
就是笨方法保证正确,聪明的方法不能保证正确。和笨方法比较,如果和笨方法的结果一致。那么就可以说明笨方法正确。
大样本测试数据。尽可能的测试各种情况。
递归函数就是系统帮忙压栈,先入后出。
归并排序,分成两部分,借组辅助数组,利用外排的方式进行归并。