赞
踩
最近在做题的过程中遇到很多排序类的题目,主要是快速排序和归并排序。因此特意总结一下十大经典排序算法,希望可以更好的理解其核心思想和特性。
首先排序算法可以分为内部排序算法和外部排序算法:在内存中进行的称为内部排序算法,也就是这里所说的这十种算法;相应的,当数据量很大时无法全部拷贝到内存需要使用外存,称为外部排序算法。接下来我们可用如下表来简单概括这十种算法:
表中数据说明:
稳定:如果A原本在B前面,而A=B,排序之后A仍然在B的前面;
不稳定:如果A原本在B的前面,而A=B,排序之后A可能会出现在B的后面;
时间复杂度: 描述一个算法执行所耗费的时间;
空间复杂度:描述一个算法执行所需内存的大小;
n:数据规模;
k:“桶”的个数;
In-place:占用常数内存,不占用额外内存;
Out-place:占用额外内存。
该十种排序算法可分为如下所示的两大类
算法步驟
代码实现
- public static void bubbleSort(int[] arr) {
- int n = arr.length;
- for (int i = 0; i < n - 1; i++) {
- for (int j = 0; j < n - i - 1; j++) {
- if (arr[j] > arr[j+1]) {
- int temp = arr[j];
- arr[j] = arr[j+1];
- arr[j+1] = temp;
- }
- }
- }
- }
算法步驟
代码实现
- public static void selectionSort(int[] arr) {
- int n = arr.length;
- for (int i = 0; i < n - 1; i++) {
- int minIndex = i;
- for (int j = i + 1; j < n; j++) {
- if (arr[j] < arr[minIndex]) {
- minIndex = j;
- }
- }
- if (minIndex != i) {
- int temp = arr[i];
- arr[i] = arr[minIndex];
- arr[minIndex] = temp;
- }
- }
- }
算法步驟
代码实现
- public class InsertionSort {
- public static void insertionSort(int[] arr) {
- for (int i = 1; i < arr.length; i++) {
- int val = arr[i], j = i;
- while (j > 0 && val < arr[j - 1]) {
- arr[j] = arr[j - 1];
- j--;
- }
- arr[j] = val;
- }
- }
- }
算法步驟
其中,增量gap=length/2,缩小增量继续以gap = gap/2的方式,这种增量选择我们可以用一个序列来表示,{n/2, (n/2)/2, …, 1},称为增量序列。一般的增量序列都选择以上说明的这个,但不一定是最优的。
代码实现
- public static void shellSort(int[] arr) {
- int n = arr.length;
- int gap = n / 2;
- while (gap > 0) {
- for (int i = gap; i < n; i++) {
- int j = i;
- int temp = arr[i];
- while (j >= gap && arr[j - gap] > temp) {
- arr[j] = arr[j - gap];
- j -= gap;
- }
- arr[j] = temp;
- }
- gap /= 2;
- }
- }
算法步驟
代码实现
- public static void mergeSort(int[] arr) {
- int n = arr.length;
- if (n < 2) {
- return;
- }
- int mid = n / 2;
- int[] left = new int[mid];
- int[] right = new int[n - mid];
- for (int i = 0; i < mid; i++) {
- left[i] = arr[i];
- }
- for (int i = mid; i < n; i++) {
- right[i - mid] = arr[i];
- }
- mergeSort(left);
- mergeSort(right);
- merge(left, right, arr);
- }
-
- public static void merge(int[] left, int[] right, int[] arr) {
- int nL = left.length;
- int nR = right.length;
- int i = 0, j = 0, k = 0;
- while (i < nL && j < nR) {
- if (left[i] <= right[j]) {
- arr[k++] = left[i++];
- } else {
- arr[k++] = right[j++];
- }
- }
- while (i < nL) {
- arr[k++] = left[i++];
- }
- while (j < nR) {
- arr[k++] = right[j++];
- }
- }
算法步驟
代码实现
- public static void quickSort(int[] arr, int left, int right) {
- if (left >= right) {
- return;
- }
- int pivotIndex = partition(arr, left, right);
- quickSort(arr, left, pivotIndex - 1);
- quickSort(arr, pivotIndex + 1, right);
- }
-
- public static int partition(int[] arr, int left, int right) {
- int pivotIndex = left;
- int pivotValue = arr[right];
- for (int i = left; i < right; i++) {
- if (arr[i] < pivotValue) {
- int temp = arr[i];
- arr[i] = arr[pivotIndex];
- arr[pivotIndex] = temp;
- pivotIndex++;
- }
- }
- int temp = arr[pivotIndex];
- arr[pivotIndex] = arr[right];
- arr[right] = temp;
- return pivotIndex;
- }
算法步驟
代码实现
- public class HeapSort {
- private static int heapLen;
-
- public static void heapSort(int[] arr) {
- heapLen = arr.length;
- for (int i = heapLen - 1; i >= 0; i--) {
- heapify(arr, i);
- }
-
- for (int i = heapLen - 1; i > 0; i--) {
- swap(arr, 0, heapLen - 1);
- heapLen--;
- heapify(arr, 0);
- }
- }
-
- private static void heapify(int[] arr, int idx) {
- int left = idx * 2 + 1, right = idx * 2 + 2, largest = idx;
- if (left < heapLen && arr[left] > arr[largest]) {
- largest = left;
- }
- if (right < heapLen && arr[right] > arr[largest]) {
- largest = right;
- }
-
- if (largest != idx) {
- swap(arr, largest, idx);
- heapify(arr, largest);
- }
- }
-
- private static void swap(int[] arr, int idx1, int idx2) {
- int tmp = arr[idx1];
- arr[idx1] = arr[idx2];
- arr[idx2] = tmp;
- }
- }
算法步驟
代码实现
- public static void countingSort(int[] arr) {
- int n = arr.length;
- if (n == 0) {
- return;
- }
- int max = arr[0], min = arr[0];
- for (int i = 1; i < n; i++) {
- if (arr[i] > max) {
- max = arr[i];
- }
- if (arr[i] < min) {
- min = arr[i];
- }
- }
- int[] count = new int[max - min + 1];
- for (int i = 0; i < n; i++) {
- count[arr[i] - min]++;
- }
- int index = 0;
- for (int i = 0; i < count.length; i++) {
- while (count[i] > 0) {
- arr[index++] = i + min;
- count[i]--;
- }
- }
- }
算法步驟
代码实现
- public static void bucketSort(int[] arr) {
- int n = arr.length;
- if (n == 0) {
- return;
- }
- int max = arr[0], min = arr[0];
- for (int i = 1; i < n; i++) {
- if (arr[i] > max) {
- max = arr[i];
- }
- if (arr[i] < min) {
- min = arr[i];
- }
- }
- int bucketSize = 10;
- int bucketCount = (max - min) / bucketSize + 1;
- List<List<Integer>> buckets = new ArrayList<>(bucketCount);
- for (int i = 0; i < bucketCount; i++) {
- buckets.add(new ArrayList<>());
- }
- for (int i = 0; i < n; i++) {
- int bucketIndex = (arr[i] - min) / bucketSize;
- buckets.get(bucketIndex).add(arr[i]);
- }
- int index = 0;
- for (int i = 0; i < bucketCount; i++) {
- List<Integer> bucket = buckets.get(i);
- Collections.sort(bucket);
- for (int j = 0; j < bucket.size(); j++) {
- arr[index++] = bucket.get(j);
- }
- }
- }
-
算法步骤
代码实现
- import java.util.ArrayList;
- import java.util.List;
-
- //基数排序
- public class RadixSort {
- public static void radixSort(int[] arr) {
- if (arr.length < 2) return;
- int maxVal = arr[0];//求出最大值
- for (int a : arr) {
- if (maxVal < a) {
- maxVal = a;
- }
- }
- int n = 1;
- while (maxVal / 10 != 0) {//求出最大值位数
- maxVal /= 10;
- n++;
- }
-
- for (int i = 0; i < n; i++) {
- List<List<Integer>> radix = new ArrayList<>();
- for (int j = 0; j < 10; j++) {
- radix.add(new ArrayList<>());
- }
- int index;
- for (int a : arr) {
- index = (a / (int) Math.pow(10, i)) % 10;
- radix.get(index).add(a);
- }
- index = 0;
- for (List<Integer> list : radix) {
- for (int a : list) {
- arr[index++] = a;
- }
- }
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。