插入排序
- 基本思想:
插入排序將序列分爲已經有序和暫時無序兩部分,遍歷暫時無序的部分,將該部分第一個元素插入到已經有序部分的合適位置,遍歷完畢則完成了排序,得到一個新的有序序列。
- 排序分類:
插入排序分爲直接插入排序和希爾排序。
一:直接插入排序
- 排序過程:
- 代碼實現:
在實際實現時爲了簡化操作,將未有序部分與有序部分的最後一個元素比較,如果不滿足排序要求則交換,繼續與倒數第二個元素比較以此類推,直到滿足排序順序爲止。
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.希爾排序是一種不穩定的排序算法