插入排序和冒泡排序时间复杂度相同,但为什么更倾向于使用插入排序而不是冒泡排序?
排序算法有很多,主要按时间复杂度分为三大类
冒泡排序(Bubble Sort)
算法
- 比较相邻两个元素
- 不满足条件的,则将他们互换
- 一次冒泡,将第一个元素移动到应有的位置
- n次完成排序工作
- 如果一次冒泡中,没有数据变化,则说明所有数据已经有序
代码
void BubbleSort(int data[], int length)
{
//BubbleSort
for (int i = 0; i < length; i++) {
bool ValueChanged = false;
for (int j = 1; j < length - i; j++) {
//不符合条件,则互换
if (data[j - 1] > data[j]) {
int tmp = data[j];
data[j] = data[j - 1];
data[j - 1] = tmp;
ValueChanged = true;
}
}
//一次完整冒泡没有数据变化,说明已经是有序的了
if (!ValueChanged) break;
}
}
特性
- 原地排序
- 稳定排序
- 空间复杂度O(1)
- 时间复杂度O(n平方)
插入排序(Insertion Sort)
算法
将未排序的数据插入到已经排序的区间中
代码
void InsertionSort(int data[], int length)
{
for (int i = 1; i < length; i++) {
//缓存比较的数据,该位置在移动有序区间是会被覆盖
int currentValue = data[i];
int j = i;
for (; j > 0; j--) {
//有序区间如果小于比较值,则移动
if (currentValue < data[j - 1] ) {
data[j] = data[j - 1];
} else {
break;
}
}
data[j] = currentValue;
}
}
特性
- 原地排序
- 稳定排序
- 空间复杂度O(1)
- 时间复杂度O(n平方)
选择排序(Selection Sort)
算法
从未排序的区间中选出最小的放到已排序的末尾
代码
void SelectSort(int data[], int length)
{
for (int i = 0; i < length - 1; i++) {
int MinIndex = i;
//i之后为未排序的
for (int j = i + 1; j < length; j++) {
if (data[MinIndex] > data[j]) {
MinIndex = j;
}
}
//i为已排序空间末尾
if (i != MinIndex) {
int tmp = data[i];
data[i] = data[MinIndex];
data[MinIndex] = tmp;
}
}
}
特性
- 原地排序
- 不稳定排序
- 空间复杂度O(1)
- 时间复杂度O(n平方)
开篇解答
冒泡排序一次移动需要3次赋值,而插入排序只需要一次赋值