原地排序
原地排序算法,就是指空间复杂度是O(1)的排序算法。
稳定性
如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变那这个算法就是稳定的排序算法,反之就是不稳定的排序算法。
冒泡排序
冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。
最好情况下时间复杂度:O(n)
最坏情况下时间复杂度:O(n²)
平均时间复杂度:O(n²)
算法代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
public void bubbleSort(int[] a, int n) { if (n <= 1) return; for (int i = 0; i < n; ++i) { boolean flag = false; for (int j = 0; j < n - i - 1; ++j) { if (a[j] > a[j+1]) { int tmp = a[j]; a[j] = a[j+1]; a[j+1] = tmp; flag = true; } } if (!flag) break; } }
|
插入排序
插入排序的思路是,首先,我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。重复这个过程,直到未排序区间中元素为空,算法结束。
最好情况下时间复杂度:O(n)
最坏情况下时间复杂度:O(n²)
平均时间复杂度:O(n²)
算法代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
public void insertionSort(int[] a, int n) { if (n <= 1) return;
for (int i = 1; i < n; ++i) { int value = a[i]; int j = i - 1; for (; j >= 0; --j) { if (a[j] > value) { a[j+1] = a[j]; } else { break; } } a[j+1] = value; } }
|
选择排序
选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。
选择排序的最好情况时间复杂度、最坏情况和平均情况时间复杂度都为 O(n2)。
选择排序是一种不稳定的排序算法。
算法代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public int[] selectionSort(int[] sourceArray) throws Exception { int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
for (int i = 0; i < arr.length - 1; i++) { int min = i; for (int j = i + 1; j < arr.length; j++) { if (arr[j] < arr[min]) { min = j; } }
if (i != min) { int tmp = arr[i]; arr[i] = arr[min]; arr[min] = tmp; }
} return arr; }
|