版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012292754/article/details/83758439
1 概念性介绍
- 原地排序(Sorted in place),就是特指空间复杂度是 O(1) 的排序算法。
- 排序算法的稳定性:待排序的序列中存在值相等的元素,经过排序后,相等元素之间的原有先后顺序不变;
排序算法 | 时间复杂度 | 是否基于比较 |
---|---|---|
冒泡、插入、选择 | O(n^2) | ✔ |
快排、归并 | O(nlogn) | ✔ |
桶、计数、基数 | O(n) | ✘ |
2 冒泡排序
冒泡排序的优势是可以检测输入序列是否已经是有序的。
// 复杂度 O(n^2)
void BubbleSort(int A[],int n){ // n 表示数据大小
for(int pass = n-1; pass >= 0; pass--) {
for(int i=0; i < pass; i++) {
if(A[i] > A[i+1]) {
int temp = A[i];
A[i] = A[j];
A[i+1] = temp;
}
}
}
}
2.1 改进冒泡排序
排序中没有交换意味着排序完成
public static void BubbleSortImproved(int A[], int n) {
int pass, i, temp;
boolean swapped = true;
for (pass = n - 1; pass >= 0 && swapped; pass--) {
swapped = false;
for (i = 0; i < pass; i++) {
if (A[i] > A[i + 1]) {
temp = A[i];
A[i] = A[i+1];
A[i+1] = temp;
swapped = true;
}
}
}
}
public static void BubbleSortImproved(int A[], int n) {
boolean flag = false;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (A[j] > A[j + 1]) {
int temp = A[j];
A[j] = A[j + 1];
A[j + 1] = temp;
flag = true;
}
}
if (!flag) break;
}
}
3 插入排序
将数组中的数据分为两个区间,已排序区间和未排序区间。初始的已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序的区间中的元素,在已经排序的区间中找到合适的位置插入,保证已排序的序列一直有序。重复这个过程,直到这个未排序的区间中的元素为空。
public static void insertSort(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; //插入数据
}
}
public static void insertSort(int a[], int n) {
int i, j, v;
for (i = 1; i < n; i++) {
v = a[i];
j = i - 1;
while (j >= 0) {
if( a[j] > v){
a[j+1] = a[j];
--j;
}
else break;
}
a[j+1] = v;
}
}
3.1 冒泡排序和插入排序的比较
冒泡和插入的时间复杂度都是 O(n^2), 为何插入比冒泡更受欢迎呢?
冒泡排序不管怎么优化,元素的交换次数是一个固定值,是原始数据的逆序度;同样插入排序也是原始数据的逆序度。但是从代码上看,冒泡的数据交换比插入的数据移动复杂,冒泡需要3个赋值操作,插入只需要一个。
3.2 希尔排序(插入排序的优化)
4 选择排序
选择排序和插入排序有些类似,也分为已排序区间和未排序区间。但是选择排序每次会从未排序的区间中找到最小元素,将其放到已排序区间的末尾。
public static void Selection(int A[], int n) {
int i, j, min, temp;
for (i = 0; i < n - 1; i++) {
min = i;
for (j = i+1; j < n; j++) {
if (A[j] < A[min]){
min = j;
}
}
temp = A[min];
A[min] = A[i];
A[i] = temp;
}
}
5 总结
是否原地排序 | 是否稳定 | 最好 | 最坏 | 平均 | |
---|---|---|---|---|---|
冒泡 | ✔ | ✔ | O(n) | O(n^2) | O(n^2) |
插入 | ✔ | ✔ | O(n) | O(n^2) | O(n^2) |
选择 | ✔ | ✘ | O(n^2) | O(n^2) | O(n^2) |