本文共 9420 字,大约阅读时间需要 31 分钟。
本文将围绕冒泡排序、桶排序、计数排序、堆排序、插入排序、并归排序、快速排序和选择排序,按照描述、时间复杂度(最坏情况)、动态图展示和代码实现来讲解。本文默认排序为从小到大。
本文相关代码已上传至github,欢迎关注
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)
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)
@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)
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)
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)
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)
@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)
@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)
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; }
转载地址:http://eqnqb.baihongyu.com/