O(n^2)排序
选择排序
//选择排序
public static void selectionSort(int[] arr) {
// 选最小的放第一个
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
int mindex = i;
for (int j = i; j < arr.length; j++) {
if (arr[mindex] > arr[j]) {
mindex = j;
}
}
swap(arr, mindex, i);
}
}
冒泡排序
//冒泡排序
public static void bubbleSort(int[] arr) {
// 大的往后冒
if (arr == null || arr.length < 2) {
return;
}
for (int i = arr.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j + 1, j);
}
}
}
}
插入排序
//插入排序
public static void insertionSort(int[] arr) {
// 往前面有序序列插入
// 最好情况O(N)
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i; j >= 0 && arr[j + 1] < arr[j]; j--) {
swap(arr, j + 1, j);
}
}
}
对数器
用来测试算法是否正确,将自己写的算法与正确的算法对比结果
public static int[] generaRandomArray(int maxSize, int maxValue) {
// Math.random()->[0,1)所有的小数,等概率返回一个
// Math.random()*N->[0,N)所有小数,等概率返回一个
// (int)(Math.random()*N)->[0,N-1]所有的整数,等概率返回一个
int[] arr = new int[(int) (Math.random() * (maxSize + 1))]; // 长度随机
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * (maxValue + 1));
// arr[i] = (int)(Math.random()*(maxValue+1)) -
// (int)(Math.random()*(maxValue));//需要负数用这个
}
return arr;
}
public static void main(String[] args) {
//对数器
int testTime = 5000;
int maxSize = 100;
int maxValue = 100;
String info = "true";
for (int i=0;i<testTime;i++){
int[] arr1 = generaRandomArray(maxSize, maxValue);
int[] arr2 = Arrays.copyOf(arr1, arr1.length);
bubbleSort(arr1);
insertionSort(arr2);
if(!Arrays.equals(arr1,arr2)){
info = "false";
break;
}
}
System.out.println(info);
}
完整代码及测试用例
CodeBlock Loading...
O(nlogn)排序
归并排序
// 归并排序
public static void mergeSort(int[] arr, int left, int right) {
if (left >= right || arr == null) {
return;
}
int mid = left + ((right - left) >> 1);
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
public static void merge(int[] arr, int left, int mid, int right) {
int[] temp = new int[right - left + 1];
int p1 = left;
int p2 = mid + 1;
int i = 0;
while (p1 <= mid && p2 <= right) { // 取小的合并
temp[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= mid) {
temp[i++] = arr[p1++];
}
while (p2 <= right) {
temp[i++] = arr[p2++];
}
for (int j = 0; j < temp.length; j++) {
arr[left + j] = temp[j];
}
}
快速排序
// 快速排序
public static void quikSort(int[] arr, int L, int R) {
if (L < R) {
int randIndex = L + (int) (Math.random() * (R - L + 1));// 选取随机位置作为枢纽
swap(arr, R, randIndex);
int p = partition2(arr, L, R);
quikSort(arr, L, p - 1);
quikSort(arr, p + 1, R);
}
}
// 单边循环划分
public static int partition1(int[] arr, int L, int R) {
int less = L - 1; // 小于区边界
for (int i = L; i < R; i++) {
if (arr[i] < arr[R]) { // 当前数小于枢纽
swap(arr, ++less, i);
}
}
swap(arr, R, less + 1);
return less + 1;
}
// 双边循环划分
public static int partition2(int[] arr, int L, int R) {
int less = L - 1;// 小于区域边界
int more = R;// 大于区域边界
int i = L;// 工作指针
while (i < more) {
if (arr[i] < arr[R]) { // 当前数<枢纽
swap(arr, ++less, i++);
} else if (arr[i] > arr[R]) { // 当前数>枢纽
swap(arr, --more, i);// i不动,因为还没有比较过
} else {
i++;
}
}
swap(arr, R, less + 1);
return less + 1;
}
堆排序
CodeBlock Loading...
排序思想应用
归并排序思想应用
求小和
CodeBlock Loading...
堆排序思想应用
相对有序排序
CodeBlock Loading...