排序算法
1. 冒泡排序
最基础排序,一句话总结冒泡排序,对于给定的数组,如果是升序排序,每一趟排序,都会把最大的元素放置在当前趟次的最后位置;
冒泡排序,只会比较交换两个相邻的元素
时间复杂度:严格O(N^2) ,和数据无关;
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
// details O(N^2) Deprecated
// end is arr.length - 1 because exist of swap i++, prevent out of index error situation happen
// outer foreach find one max num, and put it at end of arr array
// inner foreach compare two nums and swap, util to the end of end border
for (int end = arr.length - 1; end > 0; end--) {
for (int i = 0; i < end; i++) {
swap(arr, i, i + 1);
}
}
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
2. 选择排序
最基础排序,一句话总结选择排序,对于给定的数组,如果是升序排序,每次选择最小的元素放置在当前次序的第一个位置;
时间复杂度:严格O(N^2) ,和数据无关;
public static void selectionSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
// details O(N^2) Deprecated
// first loop: search 0~ N-1, find min num and put it at 0 index
// second loop: search 1~ N-1,find min num and put it at 1 index
// until foreach all array
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);
}
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
3. 插入排序
基础排序,类似扑克牌,整体思路如下(升序排)
1. 从第二个元素开始遍历,即index = 1,1个元素默认有序;
2. 对于当前元素,如果前一个元素比当前元素小,那么交换,直到前面没有元素;
3. 每次循环保证当前位置 i 之前的素有元素都是有序的;
时间复杂度:O(N^2)
1. 最好情况:如果原始数据是升序,那么插入排序的时间复杂度是O(N),因为每次都不用发生交换动作;
2. 最坏情况:如果原始数据是逆序,那么插入排序的时间复杂度是O(N^2) ,每次都要进行交换到第一个元素;
public static void insertSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
// details
for (int i = 1; i < arr.length; i++) {
int j = i - 1;
while (j > 0 && arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
j--;
}
}
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
4. 归并排序
public void mergeSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
process1(arr, 0, arr.length - 1);
}
private void process1(int[] arr, int start, int end) {
if (start == end) {
return;
}
int mid = start + (end - start) / 2;
process1(arr, start, mid);
process1(arr, mid + 1, end);
merge(arr, start, mid, end);
}
private void merge(int[] arr, int start, int mid, int end) {
int[] help = new int[end - start + 1];
int index = 0;
int p1 = start;
int p2 = mid + 1;
while (p1 <= mid && p2 <= end) {
help[index++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= mid) {
help[index++] = arr[p1++];
}
while (p2 <= end) {
help[index++] = arr[p2++];
}
for (int i = 0; i < help.length; i++) {
arr[start + i] = help[i];
}
}
5. 归并排序
public void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
process(arr, 0, arr.length - 1);
}
private void process(int[] arr, int start, int end) {
if (start >= end) {
return;
}
swap(arr, new Random().nextInt(end - start + 1) + start, end);
int[] bound = partition(arr, start, end);
process(arr, start, bound[0] - 1);
process(arr, bound[1] + 1, end);
}
private int[] partition(int[] arr, int start, int end) {
if (start > end) {
return new int[]{-1, -1};
}
if (start == end) {
return new int[]{start, end};
}
int p1 = start - 1;
int p2 = end;
int index = start;
while (index < p2) {
if (arr[index] == arr[end]) {
index++;
} else if (arr[index] < arr[end]) {
swap(arr, index++, ++p1);
} else {
swap(arr, index, --p2);
}
}
swap(arr, p2, end);
return new int[]{p1 + 1, p2};
}
public void swap(int[] arr, int x, int y) {
int tmp = arr[x];
arr[x] = arr[y];
arr[y] = tmp;
}

浙公网安备 33010602011771号