插入排序
- 基本思想:
插入排序将序列分为已经有序和暂时无序两部分,遍历暂时无序的部分,将该部分第一个元素插入到已经有序部分的合适位置,遍历完毕则完成了排序,得到一个新的有序序列。
- 排序分类:
插入排序分为直接插入排序和希尔排序。
一:直接插入排序
- 排序过程:
- 代码实现:
在实际实现时为了简化操作,将未有序部分与有序部分的最后一个元素比较,如果不满足排序要求则交换,继续与倒数第二个元素比较以此类推,直到满足排序顺序为止。
C++实现:
#include <iostream>
#include <vector>
using namespace std;
void InsertSort(vector<int>& array){
// 直接插入排序
int sz = array.size();
for (int disorder = 1; disorder < sz; disorder++){
int goal = disorder;
// 将未排序部分的第一个元素和有序部分的最后一个元素比较
while (goal > 0 && array[goal] < array[goal - 1]){
swap(array[goal], array[goal - 1]);
goal--;
}
}
}
int main(){
vector<int> array = { 5, 2, 4, 6, 1, 3};
InsertSort(array);
for (const auto& e : array){
cout << e << " ";
}
cout << endl;
}
输出结果:1 2 3 4 5 6
C实现:
#include<stdio.h>
void Swap(int* num1, int* num2){
int temp = *num1;
*num1 = *num2;
*num2 = temp;
}
void Print(int* array, int sz){
for (int cur = 0; cur < sz; cur++){
printf("%d ", array[cur]);
}
printf("\n");
}
// 插入排序传参:数组+数组大小
void InsertSort(int* array, int sz){
// 直接插入排序
for (int disorder = 1; disorder < sz; disorder++){
int goal = disorder;
while (goal > 0 && array[goal] < array[goal-1]){
Swap(&array[goal], &array[goal-1]);
goal--;
}
}
}
int main(){
int array[] = { 5, 2, 4, 6, 1, 3 };
int sz = sizeof(array) / sizeof(array[0]);
InsertSort(array, sz);
Print(array, sz);
return 0;
}
输出结果:1 2 3 4 5 6
- 特性总结:
1.时间复杂度:O(N2)
2.空间复杂度:O(1)
3.元素集合越接近有序,直接插入排序算法的时间效率越高
4.直接插入排序是一种稳定(排序后2个值相等的元素的相对位置保持不变)的排序算法
二:希尔排序
希尔排序是直接插入排序的升级版本,因为元素集合越接近有序,直接插入排序算法的时间效率越高,希尔排序旨在使用插入排序使每次排序的序列要么足够短,要么就几乎已经有序,来极大程度节省时间,提高效率。
- 排序过程:
- 代码实现:
将序列按照下标的一定增量分成若干组,对每组使用直接插入排序算法进行排序,随着增量逐渐减少,每组元素越来越多,当增量减为1时,整个序列被分为一组,此时整个序列接近有序,直接插入排序算法的时间效率大大提高。
C++实现:
#include<iostream>
#include<vector>
using namespace std;
void Shellsort(vector<int>& array){
// 设置增量并逐步缩小增量
int sz = array.size();
for (int gap = sz / 2; gap > 0; gap /= 2){
// 从第gap个元素,逐个对其所在组进行直接插入排序操作
for (int disorder = gap; disorder < sz; disorder++){
int goal = disorder;
while (goal - gap >= 0 && array[goal] < array[goal - gap]){
swap(array[goal], array[goal - gap]);
goal-=gap;
}
}
}
}
int main(){
vector<int> array = { 9, 1, 2, 5, 7, 4, 8, 6, 3, 5 };
Shellsort(array);
for (const auto& e : array){
cout << e << " ";
}
cout << endl;
}
输出结果:1 2 3 4 5 5 6 7 8 9
C实现:
#include<stdio.h>
void Swap(int* num1, int* num2){
int temp = *num1;
*num1 = *num2;
*num2 = temp;
}
void Print(int* array, int sz){
for (int cur = 0; cur < sz; cur++){
printf("%d ", array[cur]);
}
printf("\n");
}
void Shellsort(int* array, int sz){
// 设置增量并递减增量
for (int gap = sz / 2; gap > 0; gap /= 2){
// 对每组进行插入排序
for (int disorder = gap; disorder < sz; disorder++){
int goal = disorder;
while (goal-gap >= 0 && array[goal] < array[goal - gap]){
Swap(&array[goal], &array[goal - gap]);
goal -= gap;
}
}
}
}
int main(){
int array[] = { 9, 1, 2, 5, 7, 4, 8, 6, 3, 5 };
int sz = sizeof(array) / sizeof(array[0]);
Shellsort(array, sz);
Print(array, sz);
}
输出结果:1 2 3 4 5 5 6 7 8 9
- 特性总结:
1.时间复杂度:O(N1.3—N2)
2.空间复杂度:O(1)
3.希尔排序是一种不稳定的排序算法