直接插入排序
#include <iostream>
// 打印列表
template<typename T>
void print(T arr[], int len){
using namespace std;
for(int i = 0; i < len; cout << arr[i] << " ", i++);
cout << endl;
}
// 直接插入排序
template<typename T>
void insertSort(T arr[], int len){
int i, j;
T key;
for(i = 1; i < len; i++){
key = arr[i];
// 当前 key 依次与前导有序列表元素比较, 前导大则后挪
for(j = i; j > 0; j--)
if(arr[j - 1] > key)
// 当前 = 前导, 表示前导元素朝后挪动
arr[j] = arr[j - 1];
else
break;
// 插入 key
arr[j] = key;
// 打印这一轮排序结果
print<T>(arr, len);
}
}
int main(){
char chs[] = {'b', 'a', 'v', 'h', 'j', 'i'};
int vals[] = {12, 5, 2, 250, 135, 111};
// before
std::cout << "before\n";
print<char>(chs, sizeof(chs)/sizeof(char));
print<int>(vals, sizeof(vals)/sizeof(int));
insertSort<char>(chs, sizeof(chs)/sizeof(char));
insertSort<int>(vals, sizeof(vals)/sizeof(int));
// after
std::cout << "after\n";
print<char>(chs, sizeof(chs)/sizeof(char));
print<int>(vals, sizeof(vals)/sizeof(int));
return 0;
}
- 时间复杂度 最坏(逆序) - O(n*n), 最好(一次都没挪动)O(n)
冒泡排序
// 冒泡
template <typename T>
void bubbleSort(T arr[], int len){
bool swapped;
for(int i = 0; i < len; i++){
swapped = false;
for( int j = 0; j < len - i - 1; j++){
if(arr[j] > arr[j+1]){
std::swap(arr[j], arr[j+1]);
swapped = true;
}
}
print<T>(arr, len);
// 如果这一轮没有交换, 说明每个元素总是不大于后继元素, 不需要再交换了
if(!swapped)
break;
}
}
- 时间复杂度 最坏(逆序) - O(n*n), 最好(一次都没交换, 比较了n-1次)O(n)
选择排序
选择排序
与插入排序一样, 也是需要将一个序列分为前段已排序序列
和后段未排序序列
. 只不过选择排序
是在迭代循环中不停的从后段选择
最小(升序)或最大(降序)元素放置到前段已排序序列尾部; 而插入排序不选择
后段特定元素, 而是依次将后段中的每一个元素插入到前段已排序序列中适当位置.
例子
// 考虑数组 [22, 11, 33, 66, 55]
// 升序
// 第一次: 在索引 [0...4] 中选择最小元素, 放到前段尾部, 前段还没有, 放到开头
[11], [22 33 66 55]
// 第二次: 在索引 [1...4] 中查找最小元素, 放到前段尾部
[11 22], [33 66 55]
// 第三次: 在索引 [2...4]......
[11 22 33], [66 55]
// 第四次: 在索引[3...4]......
[11 22 33 55], [66]
// 第五次:
[11 22 33 55 66]
一个C++实现(降序)
#include <iostream>
#include <algorithm>
#include <string>
// 打印列表
template<typename T>
void print(T arr[], int len){
using namespace std;
for(int i = 0; i < len; cout << arr[i] << " ", i++);
cout << endl;
}
// 选择排序
template <typename T>
void selectSort(T arr[], int len){
int i, j, k; // k 为未排序子序列中的最大值的索引
for(i = 0; i < len - 1; i++){
// 在子序列中找最大, 记录最大值索引
k = i;
for(j = i + 1; j < len; j++)
if(arr[j] > arr[k])
k = j;
// 将最大值交换至当前位置
if(arr[i] < arr[k])
std::swap(arr[i], arr[k]);
print(arr, len);
}
}
int main(){
using namespace std;
int arr[] = {22, 11, 44, 33, 55};
string strs[] = {"hello", "baby", "world", "love"};
// 排序前
cout << "排序前\n";
print(arr, 5);
print(strs, 4);
// 排序中
cout << "排序中\n";
selectSort(arr, 5);
selectSort(strs, 4);
// 排序后
cout << "排序后\n";
print(arr, 5);
print(strs, 4);
return 0;
}
- 时间复杂度 O(n*n)(两个嵌套for);
- 空间复杂度 O(1)