algo/java/12_sorts/Sorts.java
2019-10-25 17:35:26 +08:00

396 lines
9.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.study.sort;
import java.util.Arrays;
/**
* 冒泡,选择,插入,快速,归并
*
* @author ldb
* @date 2019-10-08 16:09
*/
public class Sorts {
/**
* 冒泡排序
*
* @param arr
*/
public static void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length; 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;
}
}
}
}
/**
* 优化冒泡排序
*
* @param arr
*/
public static void bubbleSort2(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
boolean flag = true;
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;
flag = false;
}
}
if (flag) {
break;
}
}
}
/**
* 插入排序
*
* @param arr
*/
public static void insertSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int val = arr[i];
int index = i - 1;
while (index >= 0 && arr[index] > val) {
arr[index + 1] = arr[index];
index--;
}
arr[index + 1] = val;
}
}
/**
* 插入排序
*
* @param arr
* @param n 表示数组有用大小
*/
public static void insertSort(int[] arr, int n) {
for (int i = 1; i < n; i++) {
int val = arr[i];
int index = i - 1;
while (index >= 0 && arr[index] > val) {
arr[index + 1] = arr[index];
index--;
}
arr[index + 1] = val;
}
}
/**
* 选择排序
*
* @param arr
*/
public static void selectSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j;
}
}
// 交换
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
/**
* 归并排序
*
* @param arr
*/
public static void mergeSort(int[] arr, int left, int right) {
if (left >= right) {
return;
}
int q = (left + right) / 2;
mergeSort(arr, left, q);
mergeSort(arr, q + 1, right);
merge2(arr, left, q, right);
}
private static void merge2(int[] arr, int left, int q, int right) {
int[] leftArr = new int[q - left + 2];
int[] rightArr = new int[right - q + 1];
for (int i = 0; i <= q - left; i++) {
leftArr[i] = arr[left + i];
}
// 第一个数组添加哨兵(最大值)
leftArr[q - left + 1] = Integer.MAX_VALUE;
for (int i = 0; i < right - q; i++) {
rightArr[i] = arr[q + 1 + i];
}
// 第二个数组添加哨兵(最大值)
rightArr[right - q] = Integer.MAX_VALUE;
int i = 0;
int j = 0;
int k = left;
while (k <= right) {
// 当左边数组到达哨兵值时i不再增加直到右边数组读取完剩余值同理右边数组也一样
if (leftArr[i] <= rightArr[j]) {
arr[k++] = leftArr[i++];
} else {
arr[k++] = rightArr[j++];
}
}
}
private static void merge(int[] arr, int left, int q, int right) {
int i = left;
int j = q + 1;
int k = 0;
int[] tmp = new int[right - left + 1];
while (i <= q && j <= right) {
if (arr[i] <= arr[j]) {
tmp[k++] = arr[i++];
} else {
tmp[k++] = arr[j++];
}
}
int start = i;
int end = q;
if (j <= right) {
start = j;
end = right;
}
while (start <= end) {
tmp[k++] = arr[start++];
}
for (int l = 0; l <= right - left; l++) {
arr[l + left] = tmp[l];
}
}
/**
* 快速排序
*
* @param arr
*/
public static void quickSort(int[] arr, int left, int right) {
if (left >= right) {
return;
}
int q = partition2(arr, left, right);
quickSort(arr, left, q - 1);
quickSort(arr, q + 1, right);
}
private static int partition(int[] arr, int left, int right) {
int pivot = arr[right];
int i = left;
for (int j = left; j < right; j++) {
if (arr[j] < pivot) {
if (i == j) {
++i;
} else {
int tmp = arr[i];
arr[i++] = arr[j];
arr[j] = tmp;
}
}
}
int tmp = arr[i];
arr[i] = arr[right];
arr[right] = tmp;
return i;
}
private static int partition2(int[] arr, int left, int right) {
// 三数取中法 , 随机数在这里写
int middle = (left + right) / 2;
int pivot = arr[middle];
// 交换到最右边
int val = arr[right];
arr[right] = pivot;
arr[middle] = val;
int i = left;
for (int j = left; j < right; j++) {
if (arr[j] < pivot) {
if (i == j) {
++i;
} else {
int tmp = arr[i];
arr[i++] = arr[j];
arr[j] = tmp;
}
}
}
int tmp = arr[i];
arr[i] = arr[right];
arr[right] = tmp;
return i;
}
/**
* 三向切分快速排序
*
* @param arr
* @param left
* @param right
* @return
*/
private static void quickSort3(int[] arr, int left, int right) {
if (left >= right) {
return;
}
int l = left;
int k = left + 1;
int r = right;
int pivot = arr[l];
while (k <= r) {
if (arr[k] < pivot) {
int tmp = arr[l];
arr[l] = arr[k];
arr[k] = tmp;
l++;
k++;
} else if (arr[k] == pivot) {
k++;
} else {
if (arr[r] > pivot) {
r--;
} else if (arr[r] == pivot) {
int tmp = arr[k];
arr[k] = arr[r];
arr[r] = tmp;
k++;
r--;
} else {
int tmp = arr[l];
arr[l] = arr[r];
arr[r] = arr[k];
arr[k] = tmp;
l++;
k++;
r--;
}
}
}
quickSort(arr, left, l - 1);
quickSort(arr, r + 1, right);
}
/**
* 双轴快速排序
*
* @param arr
* @param left
* @param right
*/
private static void quickSort4(int[] arr, int left, int right) {
if (left >= right) {
return;
}
int l = left;
int k = left + 1;
int r = right;
// 判断pivot1 与 pivot2 大小
if (arr[l] > arr[r]) {
int tmp = arr[l];
arr[l] = arr[r];
arr[r] = tmp;
}
int pivot1 = arr[l];
int pivot2 = arr[r];
while (k < r) {
if (arr[k] < pivot1) {
l++;
if (l != k) {
int tmp = arr[l];
arr[l] = arr[k];
arr[k] = tmp;
}
k++;
} else if (arr[k] >= pivot1 && arr[k] <= pivot2) {
k++;
} else {
--r;
if (arr[r] > pivot2) {
} else if (arr[r] >= pivot1 && arr[r] <= pivot2) {
int tmp = arr[k];
arr[k] = arr[r];
arr[r] = tmp;
k++;
} else {
l++;
int tmp = arr[l];
arr[l] = arr[r];
arr[r] = arr[k];
arr[k] = tmp;
k++;
}
}
}
// 交换pivot1 和 pivot2
arr[left] = arr[l];
arr[l] = pivot1;
arr[right] = arr[r];
arr[r] = pivot2;
quickSort(arr, left, l - 1);
quickSort(arr, l + 1, r - 1);
quickSort(arr, r + 1, right);
}
/**
* O(n) 时间复杂度内求无序数组中的第 K 大元素。比如, 4 2 5 12 3 这样一组数据,第 3 大元素就是 4 。
*
* @param arr
*/
public static int sort(int[] arr, int l, int r, int k) {
if (l >= r) {
return 0;
}
int p = partition(arr, l, r);
if ((p + 1) == k) {
return arr[p];
} else if ((p + 1) < k) {
return sort(arr, p + 1, r, k);
} else {
return sort(arr, l, p - 1, k);
}
}
public static void main(String[] args) {
int[] arr = {2, 1, 5, 6, 8, 4, 12, 11, 13, 15, 7, 9, 0, -1};
// bubbleSort(arr);
// bubbleSort2(arr);
// selectSort(arr);
// mergeSort(arr, 0, arr.length - 1);
// quickSort4(arr, 0, arr.length - 1);
Arrays.sort(arr);
print(arr);
}
public static void print(int[] arr) {
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
}
}