经典排序算法练习

来源:互联网 发布:最好的英文翻译软件 编辑:程序博客网 时间:2024/06/05 22:39

直接插入排序

#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;}

insertSort

  • 时间复杂度 最坏(逆序) - 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;}

selectionSort

  • 时间复杂度 O(n*n)(两个嵌套for);
  • 空间复杂度 O(1)
原创粉丝点击