- 冒泡排序
- 选择排序
- 插入排序
- 快速排序
- 归并排序
- 堆排序
时间复杂度参考:
https://blog.youkuaiyun.com/weiwenhp/article/details/8622728
排序方法 | 平均时间 | 最好时间 | 最坏时间 |
桶排序(不稳定) | O(n) | O(n) | O(n) |
基数排序(稳定) | O(n) | O(n) | O(n) |
归并排序(稳定) | O(nlogn) | O(nlogn) | O(nlogn) |
快速排序(不稳定) | O(nlogn) | O(nlogn) | O(n^2) |
堆排序(不稳定) | O(nlogn) | O(nlogn) | O(nlogn) |
希尔排序(不稳定) | O(n^1.25) | ||
冒泡排序(稳定) | O(n^2) | O(n) | O(n^2) |
选择排序(不稳定) | O(n^2) | O(n^2) | O(n^2) |
直接插入排序(稳定) | O(n^2) | O(n) | O(n^2) |
一、冒泡排序
package sort;
import com.alibaba.fastjson.JSON;
/**
* 冒泡排序
* 时间复杂度:平均:O(n^2),最好:O(n),最坏:O(n^2)
* 稳定性:稳定
*/
public class BubbleSort {
public static void main(String[] args) {
int[] a = {4,5,2,3,5,7,9,0};
bubbleSort(a);
System.out.println(JSON.toJSONString(a));
}
private static void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j+1] < arr[j]) {
exch(arr, j, j + 1);
}
}
}
}
private static void exch(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
二、选择排序
package sort;
import com.alibaba.fastjson.JSON;
/**
* 选择排序
* 时间复杂度:平均:O(n^2),最好:O(n^2),最坏:O(n^2)
* 稳定性:不稳定
*/
public class SelectSort {
public static void main(String[] args) {
int[] a = { 4, 5, 2, 3, 5, 1, 7, 9, 0 };
selectSort(a);
System.out.println(JSON.toJSONString(a));
}
private static void selectSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int min = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
if (min != i) {
exch(arr, i, min);
}
}
}
private static void exch(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
三、插入排序
package sort;
import com.alibaba.fastjson.JSON;
/**
* 插入排序 时间复杂度
* 平均:O(n^2),最好:O(n),最坏:O(n^2)
* 稳定性:稳定
*/
public class InsertSort {
public static void main(String[] args) {
int[] a = { 4, 5, 2, 3, 5, 1, 7, 9, 0 };
insertSort(a);
System.out.println(JSON.toJSONString(a));
}
private static void insertSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
for (int j = i; j > 0; j--) {
if (arr[j] >= arr[j - 1]) {
break;
}
exch(arr, j, j - 1);
}
}
}
private static void exch(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
四、快速排序
package sort;
import com.alibaba.fastjson.JSON;
/**
* 快速排序
* 时间复杂度:平均:O(nlogn),最好:O(nlogn) O(n^2)
* 稳定性:不稳定
*/
public class QuickSort {
public static void main(String[] args) {
int[] a = { 4, 5, 2, 3, 5, 1, 7, 9, 0, 6 };
quickSort(a, 0, a.length - 1);
System.out.println(JSON.toJSONString(a));
}
private static void quickSort(int[] arr, int lo, int hi) {
if (hi <= lo) {
return;
}
int j = partition(arr, lo, hi);
quickSort(arr, lo, j - 1);
quickSort(arr, j + 1, hi);
}
private static int partition(int[] arr, int lo, int hi) {
int i = lo;
int j = hi + 1;
while (true) {
// i 向右移动
while (arr[++i] < arr[lo]) {
if (i == hi) {
break;
}
}
// j 向左移动
while (arr[--j] > arr[lo]) {
if (j == lo) {
break;
}
}
if (i >= j) {
break;
}
exch(arr, i, j);
}
exch(arr, lo, j);
return j;
}
private static void exch(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
五、归并排序
package sort;
import com.alibaba.fastjson.JSON;
import java.util.Arrays;
/**
* 归并排序
* 时间复杂度:平均:O(nlogn),最好:O(nlogn),最坏:O(nlogn)
* 稳定性:稳定
*/
public class MergeSort {
public static void main(String[] args) {
int[] a = { 4, 5, 2, 3, 5, 1, 7, 9, 0, 6 };
mergeSort(a, 0, a.length - 1);
System.out.println(JSON.toJSONString(a));
}
private static void mergeSort(int[] arr, int lo, int hi) {
if (hi <= lo) {
return;
}
int mid = lo + (hi - lo) / 2;
mergeSort(arr, lo, mid);
mergeSort(arr, mid + 1, hi);
merge(arr, lo, mid, hi);
}
// 原地归并
private static void merge(int[] arr, int lo, int mid, int hi) {
// 拷贝一份新的数组
int[] tempArr = Arrays.copyOf(arr, arr.length);
int i = lo;
int j = mid+ 1;
for (int k = lo; k <= hi; k++) {
if (i > mid) {
arr[k] = tempArr[j++];
} else if (j > hi) {
arr[k] = tempArr[i++];
} else if (tempArr[i] < tempArr[j]) {
arr[k] = tempArr[i++];
} else {
arr[k] = tempArr[j++];
}
}
}
}
六、堆排序
package sort;
import com.alibaba.fastjson.JSON;
/**
* 堆排序
* 时间复杂度:平均:O(nlogn),最好:O(nlogn),最好:O(nlogn)
* 稳定性:不稳定
*/
public class HeapSort {
public static void main(String[] args) {
int[] a = { 4, 5, 2, 3, 5, 1, 7, 9, 0, 6 };
heapSort(a);
System.out.println(JSON.toJSONString(a));
}
private static void heapSort(int[] arr) {
MaxHeap maxHeap = new MaxHeap(arr);
maxHeap.heapSort();
}
/**
* 大顶堆
*/
private static class MaxHeap {
// 容器
private int[] array;
// 记录当前保存了多少元素
private int count;
// 容量
private int capacity;
public MaxHeap(int capacity) {
this.capacity = capacity;
this.count = 0;
this.array = new int[capacity];
}
public MaxHeap(int[] array) {
this.capacity = array.length;
this.count = 0;
this.array = array;
buildMaxHeap(array);
}
/**
* 数组建堆
* @param arr
*/
public void buildMaxHeap(int[] arr) {
while (arr.length > this.capacity) {
// 数组数据超过容量,需要扩容
resize();
}
this.count = arr.length;
for (int i = 0; i < arr.length; i++) {
this.array[i] = arr[i];
}
// 从第一个非叶子节点位置开始下沉堆化
for (int i = (this.count - 1) / 2; i >= 0; i--) {
this.downForward(i);
}
}
/**
* 堆排序
* @return
*/
public int[] heapSort() {
int[] sortedArr = new int[count];
int oldCount = this.count;
for (int i = this.count - 1; i > 0; i--) {
// 交换最后一个leaf节点和root
exch(0, i);
this.count--;
// root下沉堆化
downForward(0);
}
for (int i = 0; i < oldCount; i++) {
sortedArr[i] = this.array[i];
}
this.count = oldCount;
return sortedArr;
}
/**
* 父节点在数组中的位置
* @param i
* @return
*/
public int parentIdx(int i) {
if (i <= 0 || i >= this.count) {
return -1;
}
return (i - 1) / 2;
}
/**
* 左子节点在数组中的位置
* @return
*/
private int leftChildIdx(int i) {
int left = 2 * i + 1;
if (left >= this.count) {
return -1;
}
return left;
}
/**
* 右子节点在数组中的位置
* @param i
* @return
*/
private int rightChildIdx(int i) {
int right = 2 * i + 2;
if (right >= this.count) {
return -1;
}
return right;
}
/**
* 从节点i开始下沉堆化
* @param i
*/
private void downForward(int i) {
if (i >= this.count - 1) {
return;
}
int left = this.leftChildIdx(i);
int right = this.rightChildIdx(i);
// 比较节点i与左、右子节点
int maxIdx = this.maxIdx(i, left, right);
if (maxIdx == -1 || maxIdx == i) {
// 没有子节点了,或者左右子节点都比自己小,就结束
return;
}
// 下沉
this.exch(i, maxIdx);
// 继续下沉
downForward(maxIdx);
}
private int maxIdx(int i, int left, int right) {
if (left == -1 && right == -1) {
return -1;
}
int max = i;
if (left != -1) {
if (this.array[left] > this.array[max]) {
max = left;
}
}
if (right != -1) {
if (this.array[right] > this.array[max]) {
max = right;
}
}
return max;
}
private void exch(int i, int j) {
int tmp = this.array[i];
this.array[i] = this.array[j];
this.array[j] = tmp;
}
/**
* 双倍扩容
*/
private void resize() {
int[] oldArr = this.array;
this.array = new int[this.capacity * 2];
for (int i = 0; i < this.capacity; i++) {
this.array[i] = oldArr[i];
}
this.capacity = capacity * 2;
}
public int size() {
return this.count;
}
/**
* 分层打印
*/
public void printHeapByLayer() {
int history = 0;
int h = 0;
while (history < this.count) {
System.out.print("layer_" + h + ": ");
int layerCnt = 1 << h;
int remain = this.count - history;
int printSize = Math.min(remain, layerCnt);
for (int i = history; i < history + printSize - 1; i++) {
System.out.print(this.array[i] + ",");
}
System.out.println(this.array[history + printSize - 1]);
history += printSize;
h++;
}
}
}
}