本文将围绕冒泡排序、桶排序、计数排序、堆排序、插入排序、并归排序、快速排序和选择排序,按照描述、时间复杂度(最坏情况)、动态图展示和代码实现来讲解。本文默认排序为从小到大。
本文相关代码已上传至github,欢迎关注https://github.com/zhuzhenke/common-algorithms
SortUtils
public class SortUtils {
public static void check(int[] sortingData) {
if (sortingData == null || sortingData.length == 0) {
throw new IllegalArgumentException("sortingData can not be empty!");
}
}
public static void swap(int[] swapArray, int i, int j) {
check(swapArray);
if (i < 0 || i > swapArray.length - 1) {
throw new ArrayIndexOutOfBoundsException("illegal index i:" + i);
}
if (j < 0 || j > swapArray.length - 1) {
throw new ArrayIndexOutOfBoundsException("illegal index j:" + j);
}
int temp = swapArray[i];
swapArray[i] = swapArray[j];
swapArray[j] = temp;
}
public static int getMaxValue(int[] sortingData) {
check(sortingData);
int max = sortingData[0];
for (int value : sortingData) {
if (value < 0) {
throw new IllegalArgumentException("value could not be negative:" + value);
}
if (value > max) {
max = value;
}
}
return max;
}
}
O(n^2)
github代码
public int[] sort(int[] sortingData) {
SortUtils.check(sortingData);
for (int j = sortingData.length - 1; j > 0; j--) {
for (int i = 0; i < j; i++) {
if (sortingData[i] > sortingData[i + 1]) {
SortUtils.swap(sortingData, i, i + 1);
}
}
}
return sortingData;
}
O(n^2)
github代码
@Override
public int[] sort(int[] sortingData) {
SortUtils.check(sortingData);
int bucketSize = (int) Math.round(Math.sqrt(sortingData.length)) + 1;
int[][] buckets = new int[bucketSize][];
int max = SortUtils.getMaxValue(sortingData);
double avgContain = Math.ceil((double) max / (double) bucketSize);
for (int value : sortingData) {
int bucketIndex = (int) Math.ceil(value / avgContain) - 1;
if (bucketIndex < 0) {
bucketIndex = 0;
}
int[] bucketIndexs = buckets[bucketIndex];
if (bucketIndexs == null || bucketIndexs.length == 0) {
bucketIndexs = new int[1];
bucketIndexs[0] = value;
buckets[bucketIndex] = bucketIndexs;
} else {
int[] newBucketIndexs = new int[bucketIndexs.length + 1];
System.arraycopy(bucketIndexs, 0, newBucketIndexs, 0, bucketIndexs.length);
newBucketIndexs[bucketIndexs.length] = value;
buckets[bucketIndex] = newBucketIndexs;
}
}
Sort sort = new InsertionSort();
for (int a = 0; a < buckets.length; a++) {
int[] bucket = buckets[a];
if (bucket == null || bucket.length == 0) {
continue;
}
bucket = sort.sort(bucket);
buckets[a] = bucket;
}
int[] result = new int[sortingData.length];
int resultIndex = 0;
for (int[] bucket : buckets) {
if (bucket == null || bucket.length == 0) {
continue;
}
for (int bucketValue : bucket) {
result[resultIndex++] = bucketValue;
}
}
return result;
}
O(n)
github代码
private int[] sort2(int[] sortingData) {
int maxValue = SortUtils.getMaxValue(sortingData);
//get max,check all numbers must be bigger or equal 0
int[] count = new int[maxValue + 1];
//count every number
for (int value : sortingData) {
count[value] = count[value] + 1;
}
for (int i = 1; i < count.length; i++) {
count[i] = count[i] + count[i - 1];
}
//output
int[] result = new int[sortingData.length];
for (int value : sortingData) {
result[count[value] - 1] = value;
count[value] = count[value] - 1;
}
return result;
}
O(nlogn)
github代码
public int[] sort(int[] sortingData) {
int highIndex = sortingData.length - 1;
while (highIndex > 0) {
for (int i = 1; i <= highIndex; i++) {
sortBiggestToIndex0(sortingData, i);
}
SortUtils.swap(sortingData, 0, highIndex);
highIndex--;
}
return sortingData;
}
public static void sortBiggestToIndex0(int[] sortingData, int sortIndex) {
while (sortIndex > 0 && sortingData[sortIndex] > sortingData[(sortIndex - 1) / 2]) {
SortUtils.swap(sortingData, sortIndex, (sortIndex - 1) / 2);
sortIndex = (sortIndex - 1) / 2;
}
}
O(n^2)
github代码
public int[] sort(int[] sortingData) {
SortUtils.check(sortingData);
for (int i = 1; i < sortingData.length; i++) {
int currentValue = sortingData[i];
int j = i;
while (j - 1 >= 0 && currentValue < sortingData[j - 1]) {
sortingData[j] = sortingData[j - 1];
j--;
}
sortingData[j] = currentValue;
}
return sortingData;
}
O(nlogn)
github代码
@Override
public int[] sort(int[] sortingData) {
SortUtils.check(sortingData);
splitDate(sortingData, 0, sortingData.length - 1);
return sortingData;
}
private void splitDate(int[] sortingData, int start, int end) {
if (end - start < 1) {
return;
}
int middle = (start + end) / 2;
splitDate(sortingData, start, middle);
splitDate(sortingData, middle + 1, end);
mergeData(sortingData, start, middle, end);
}
private void mergeData(int[] sortingData, int start, int middle, int end) {
int[] left = Arrays.copyOfRange(sortingData, start, middle + 1);
int[] right = Arrays.copyOfRange(sortingData, middle + 1, end + 1);
int i = 0;
int j = 0;
for (int k = start; k <= end; k++) {
if (i < left.length && j < right.length) {
if (left[i] <= right[j]) {
sortingData[k] = left[i];
i++;
} else {
sortingData[k] = right[j];
j++;
}
} else {
if (i >= left.length) {
sortingData[k] = right[j];
j++;
} else if (j >= right.length) {
sortingData[k] = left[i];
i++;
}
}
}
}
O(n^2)
github代码
@Override
public int[] sort(int[] sortingData) {
SortUtils.check(sortingData);
quickSort(sortingData, 0, sortingData.length - 1);
return sortingData;
}
private void quickSort(int[] sortingData, int start, int end) {
if (start > end) {
return;
}
int middle = getQuickSortMiddle(sortingData, start, end);
quickSort(sortingData, start, middle - 1);
quickSort(sortingData, middle + 1, end);
}
/**
* one side
*/
public int getQuickSortMiddle(int[] sortingData, int start, int end) {
int i = start;
int pivot = end;
for (int j = start; j < end; j++) {
if (sortingData[j] < sortingData[pivot]) {
SortUtils.swap(sortingData, i, j);
i++;
}
}
SortUtils.swap(sortingData, i, pivot);
return i;
}
O(n^2)
github代码
public int[] sort(int[] sortingData) {
SortUtils.check(sortingData);
for (int index = 0; index < sortingData.length; index++) {
int smallestIndex = index;
int smallestValue = sortingData[index];
for (int j = index; j < sortingData.length; j++) {
if (sortingData[j] < smallestValue) {
smallestValue = sortingData[j];
smallestIndex = j;
}
}
sortingData[smallestIndex] = sortingData[index];
sortingData[index] = smallestValue;
}
return sortingData;
}