算法复杂度
十大经典排序算法(动图演示) - 一像素 - 博客园 https://www.cnblogs.com/onepixel/p/7674659.html
排序方法 | 时间复杂化度(最好) | 时间复杂度(平均) | 时间复杂度(最坏) | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | O( n n ) | O() | O( n2 n 2 ) | O(1) | 稳定 |
选择排序 | O( n2 n 2 ) | O( n2 n 2 ) | O( n2 n 2 ) | O(1) | 不稳定 |
插入排序 | O( n n ) | O() | O( n2 n 2 ) | O(1) | 稳定 |
归并排序 | O( nlog2n n l o g 2 n ) | O( nlog2n n l o g 2 n ) | O( nlog2n n l o g 2 n ) | O(n) | 稳定 |
快速排序 | O( nlog2n n l o g 2 n ) | O( nlog2n n l o g 2 n ) | O( n2 n 2 ) | O( nlog2n n l o g 2 n ) | 不稳定 |
希尔排序 | O( n n ) | O() | O( n2 n 2 ) | O(1) | 不稳定 |
计数排序 | O( n+k n + k ) | O( n+k n + k ) | O( n+k n + k ) | O( n+k n + k ) | 稳定 |
基数排序 | O( n∗k n ∗ k ) | O( n∗k n ∗ k ) | O( n∗k n ∗ k ) | O( n+k n + k ) | 稳定 |
堆排序 | O( nlog2n n l o g 2 n ) | O( nlog2n n l o g 2 n ) | O( nlog2n n l o g 2 n ) | O(1) | 不稳定 |
桶排序 | O( n n ) | O() | O( n+k n + k ) | O( n+k n + k ) | 稳定 |
JAVA常见五种排序算法
搞懂基本排序算法 - 掘金 https://juejin.im/post/5a96d6b15188255efc5f8bbd
冒泡排序
public class BubbleSortDemo {
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
private static void printArr(int[] arr) {
for (int anArr : arr) {
System.out.print(anArr + " ");
}
}
private static void bubbleSort(int[] arr) {
if (arr == null)
return;
// 定义一个标记 isSort,当其值为 true 的时候代表已经有序。
boolean isSort;
for (int i = 0; i < arr.length - 1; i++) {
isSort = true;
for (int j = 1; j < arr.length - i; j++) {
if (arr[j - 1] > arr[j]) {
swap(arr, j - 1, j);
isSort = false;
}
}
if (isSort)
break;
}
}
public static void main(String[] args) {
int[] arr = {6, 4, 2, 1, 8, 3, 7, 9, 5};
bubbleSort(arr);
printArr(arr);
}
}
选择排序
public class SelectSortDemo {
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
private static void printArr(int[] arr) {
for (int anArr : arr) {
System.out.print(anArr + " ");
}
}
private static void selectSort(int[] arr) {
if (arr == null)
return;
int i, j, min, len = arr.length;
for (i = 0; i < len - 1; i++) {
min = i; // 未排序的序列中最小元素的下标
for (j = i + 1; j < len; j++) {
//在未排序元素中继续寻找最小元素,并保存其下标
if (arr[min] > arr[j]) {
min = j;
}
}
if (min != i)
swap(arr, min, i);
}
}
public static void main(String[] args) {
int[] arr = {6, 4, 2, 1, 8, 3, 7, 9, 5};
selectSort(arr);
printArr(arr);
}
}
插入排序
public class InsertionSortDemo( {
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
private static void printArr(int[] arr) {
for (int anArr : arr) {
System.out.print(anArr + " ");
}
}
private static void insertionSort(int[] arr) {
if (arr == null)
return;
int j;
int temp;
for (int i = 1; i < arr.length; i++) {
// 设置哨兵,拿出待插入的值
temp = arr[i];
j = i;
// 然后寻找正确插入的位置
while (j > 0 && arr[j - 1] > temp) {
arr[j] = arr[j - 1];
j--;
}
arr[j] = temp;
}
}
public static void main(String[] args) {
int[] arr = {6, 4, 2, 1, 8, 3, 7, 9, 5};
insertionSort(arr);
printArr(arr);
}
}
归并排序
public class MergeSortDemo {
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
private static void printArr(int[] arr) {
for (int anArr : arr) {
System.out.print(anArr + " ");
}
}
private static void mergeSort(int[] arr) {
if (arr == null)
return;
mergeSort(arr, 0, arr.length - 1);
}
private static void mergeSort(int[] arr, int start, int end) {
if (start >= end)
return;
// 找出中间索引
int mid = start + (end - start >> 1);
// 对左边数组进行递归
mergeSort(arr, start, mid);
// 对右边数组进行递归
mergeSort(arr, mid + 1, end);
// 合并
merge(arr, start, mid, end);
}
private static void merge(int[] arr, int start, int mid, int end) {
// 先建立一个临时数组,用于存放排序后的数据
int[] tmpArr = new int[arr.length];
int start1 = start, end1 = mid, start2 = mid + 1, end2 = end;
// 创建一个下标
int pos = start1;
// 缓存左边数组的第一个元素的索引
int tmp = start1;
while (start1 <= end1 && start2 <= end2) {
// 从两个数组中取出最小的放入临时数组
if (arr[start1] <= arr[start2])
tmpArr[pos++] = arr[start1++];
else
tmpArr[pos++] = arr[start2++];
}
// 剩余部分依次放入临时数组,实际上下面两个 while 只会执行其中一个
while (start1 <= end1) {
tmpArr[pos++] = arr[start1++];
}
while (start2 <= end2) {
tmpArr[pos++] = arr[start2++];
}
// 将临时数组中的内容拷贝回原来的数组中
while (tmp <= end) {
arr[tmp] = tmpArr[tmp++];
}
}
public static void main(String[] args) {
int[] arr = {6, 4, 2, 1, 8, 3, 7, 9, 5};
mergeSort(arr);
printArr(arr);
}
}
快速排序
public class QuickSortDemo{
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
private static void printArr(int[] arr) {
for (int anArr : arr) {
System.out.print(anArr + " ");
}
}
private static int partition(int[] arr, int left, int right) {
// 采用三数中值分割法
int mid = left + (right - left) / 2;
// 保证左端较小
if (arr[left] > arr[right])
swap(arr, left, right);
// 保证中间较小
if (arr[mid] > arr[right])
swap(arr, mid, right);
// 保证中间最小,左右最大
if (arr[mid] > arr[left])
swap(arr, left, mid);
int pivot = arr[left];
while (right > left) {
// 先判断基准数和后面的数依次比较
while (pivot <= arr[right] && left < right) {
--right;
}
// 当基准数大于了 arr[right],则填坑
if (left < right) {
arr[left] = arr[right];
++left;
}
// 现在是 arr[right] 需要填坑了
while (pivot >= arr[left] && left < right) {
++left;
}
if (left < right) {
arr[right] = arr[left];
--right;
}
}
arr[left] = pivot;
return left;
}
private static void quickSort(int[] arr, int left, int right) {
if (arr == null || left >= right || arr.length <= 1)
return;
int mid = partition(arr, left, right);
quickSort(arr, left, mid);
quickSort(arr, mid + 1, right);
}
public static void main(String[] args) {
int[] arr = {6, 4, 3, 2, 7, 9, 1, 8, 5};
quickSort(arr, 0, arr.length - 1);
printArr(arr);
}
}