您的位置:首页 > 其它

经典排序算法练习

2017-09-17 14:44 218 查看

直接插入排序

#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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序算法