文章目录
排序算法的评价标准
1、时间复杂度:即从序列的初始状态到经过排序算法的变换移位等操作变到最终排序好的结果状态的过程所花费的时间度量。
2、空间复杂度:就是从序列的初始状态经过排序移位变换的过程一直到最终的状态所花费的空间开销。
3、稳定性:经过排序之后,相同关键字的记录的相对次序保持不变。在原序列中排序前,r[i]在r[j]前面,排序之后r[i]仍然在r[j]之后称该排序算法是稳定的;否则为不稳定的。
插入排序
直接插入排序
算法分析
int[] arr = new int[] {0, 6, 8, 1, 1, 5};
基本思想:每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。
假设有一组无序序列 R0, R1, … , RN-1。
(1) 我们先将这个序列中下标为 0 的元素视为元素个数为 1 的有序序列。
(2) 然后,依次把 R1, R2, … , RN-1 插入到这个有序序列中。所以,我们需要一个外部循环,从下标 1 扫描到 N-1 。
(3) 接下来描述插入过程。假设这是要将 Ri 插入到前面有序的序列中。由前面所述,我们可知,插入Ri时,前 i-1 个数肯定已经是有序了。
所以我们需要将Ri 和R0 ~ Ri-1 进行比较,确定要插入的合适位置。这就需要一个内部循环,从下标 i-1 开始向 0 进行扫描。
public void insertSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int insert = arr[i];
int j;
for (j = i - 1; j >= 0 && insert < arr[j]; j--) {
arr[j + 1] = arr[j];
}
arr[j + 1] = insert;
}
}
平均时间、空间复杂度及稳定性
平均时间复杂度:O(n^2)
平均空间复杂度:O(1)
稳定性:不稳定
希尔排序
算法分析
int[] arr = new int[] {8, 6, 2, 3, 1, 2};
希尔排序跟直接插入排序很相似,是在直接插入排序的基础上增加了一个分组的功能。
public void shellSort(int[] arr) {
int gap = arr.length;
while (true) {
gap = gap/3 + 1;
insertSortWithGap(arr, gap);
if (gap == 1) {
return;
}
}
}
public void insertSortWithGap(int[] arr, int gap) {
for (int i = gap; i < arr.length; i++) {
int insert = arr[i];
int j;
for (j = i - gap; j >= 0 && arr[j] > insert; j -= gap){
arr[j + gap] = arr[j];
}
arr[j + gap] = insert;
}
}
平均时间、空间复杂度及稳定性
平均时间复杂度:O(n^1.3)
平均空间复杂度:O(1)
稳定性:不稳定
选择排序
直接选择排序
算法分析
int[] arr = new int[] {6, 4, 4, 1, 7, 3};
在要排序的一组数中,选出最小的一个数与第1个位置的数交换,然后在剩下的数当中再找最小的与第2个位置的数交换,以此类推,直到倒数第二个与倒数第一个比较为止。
public int[] selectSort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
swap(arr, i, minIndex);
}
return arr;
}
private void swap(int[] arr, int i, int j) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
蓝色线左边的为有序区间