排序算法

来源:互联网 发布:学中文的软件 编辑:程序博客网 时间:2024/05/29 15:19

排序算法小结


1.冒泡排序 BubbleSort

冒泡排序是一种简单的排序算法,它重复遍历待排序列,并以正确的顺序交换相邻元素的位置。当所有的交换完成后,该待排序列完成排序。

实现如下:

void my_sort::MySort::BubbleSort0(std::vector<int> &i_arr){    size_t i_arr_len = i_arr.size();    for (size_t i = 0; i < i_arr_len; i++)    {        for (size_t j = 0; j < i_arr_len; j++)        {            if (i_arr[i] < i_arr[j])            {                my_sort::my_swap(i_arr[i], i_arr[j]);            }        }    }}void my_sort::MySort::BubbleSort(std::vector<int> &i_arr){    size_t i_arr_len = i_arr.size();    for (int i = 0; i < i_arr_len; i++)    {        for (int j = i_arr_len - 2; j >= i; j--)        {            if (i_arr[j] > i_arr[j + 1])                my_sort::my_swap(i_arr[j], i_arr[j + 1]);        }    }}

注:后者是冒泡排序的一种常用做法。


2.选择排序 Selection Sort

选择排序是一种直观的排序算法,其原理是每次选出待排序列中的最小值放于恰当的位置,所有交换完成后即完成排序工作。
实现如下:

void my_sort::MySort::SelectSort(std::vector<int>& i_arr){    size_t i_arr_len = i_arr.size();    for (int i = 0; i < i_arr_len; i++)    {        int min = i;        for (int j = i + 1; j < i_arr_len; j++)        {            if (i_arr[j] < i_arr[min])                min = j;        }        if (i != min)            my_sort::my_swap(i_arr[i], i_arr[min]);    }}

3.直接插入排序 InsertSort

直接插入排序是一种简单有效的排序算法,其原理与扑克牌理牌原理类似,即将单个数据插入到已经排序好的有序序列中,当最后一个元素完成插入时,整个待排序列完成排序。
实现如下:

void my_sort::MySort::InsertSort(std::vector<int>& i_arr){    size_t i_arr_len = i_arr.size();    for (int i = 0; i < i_arr_len - 1; i++)    {        int j;        if (i_arr[i] > i_arr[i + 1])        {            int tmp = i_arr[i + 1];            for (j = i + 1; j > 0 && tmp < i_arr[j - 1]; j--)            {                i_arr[j] = i_arr[j - 1];            }            i_arr[j] = tmp;        }    }}

4.希尔排序 ShellSort

希尔排序是插入排序的一种,是直接插入排序的改进版本。
实现如下:

void my_sort::MySort::ShellSort(std::vector<int>& i_arr){    size_t i_arr_len = i_arr.size();    for (int increment = i_arr_len / 2; increment > 0; increment /= 2)    {        for (int i = increment; i < i_arr_len; i++)        {            int tmp = i_arr[i];            int j;            for (j = i; j >= increment && i_arr[j - increment] > tmp; j -= increment)                i_arr[j] = i_arr[j - increment];            i_arr[j] = tmp;        }    }}

5.归并排序 MergeSort

归并排序是典型的使用分治法的算法案例。其基本过程是将待排序列分割个单个元素,再将有序子序列合并,得到完全的有序序列。
递归实现如下:

void my_sort::MySort::MergeSort(std::vector<int>& i_arr){    MSort(i_arr, 0, i_arr.size() - 1);}void my_sort::MySort::MSort(std::vector<int>& SR, int Left, int Right){    if (Left == Right)        return;    int Center = (Left + Right) / 2;    MSort(SR, Left, Center);    MSort(SR, Center + 1, Right);    Merge(SR, Left, Center, Right);}void my_sort::MySort::Merge(std::vector<int>& SR, int Lpos, int mid, int Rpos){    std::vector<int> tmp(SR.size());    int i = Lpos;    int m = mid;    int n = Rpos;    int j, k, l;    for (j = m + 1, k = i; i <= m && j <= n; k++)    {        if (SR[i] < SR[j])            tmp[k] = SR[i++];        else            tmp[k] = SR[j++];    }    if (i <= m)    {        for (l = 0; l <= m - i; l++)            tmp[k + l] = SR[i + l];    }    if (j <= n)    {        for (l = 0; l <= n - j; l++)            tmp[k + l] = SR[j + l];    }    for (int idx = Lpos; idx <= Rpos; idx++)        SR[idx] = tmp[idx];}

6.快速排序 QuickSort

快速排序算法别列为20世纪十大算法之一,其基本思想是通过一趟排序将要排序的数据分割成独立的两部分,再对这两部分进行快速排序,最终使待排序列变为有序序列。
递归实现如下:

void my_sort::MySort::QuickSort(std::vector<int>& i_arr, int low, int high){    int pivot;    if (low < high)    {        int tmp = i_arr[low];        int i = low;        int j = high;        while (i < j)        {            while (i < j && tmp <= i_arr[j])                j--;            my_sort::my_swap_val(i_arr[i], i_arr[j]);            //my_sort::my_swap(i_arr[i], i_arr[j]);            while (i < j && tmp >= i_arr[i])                i++;            my_sort::my_swap_val(i_arr[i], i_arr[j]);            //my_sort::my_swap(i_arr[i], i_arr[j]);        }        QuickSort(i_arr, low, i - 1);        QuickSort(i_arr, i + 1, high);    }}

注:此处遇到一个问题,自己实现的swap函数有时会将元素变为0。检查的原因是swap函数是由位运算实现的,当交换参数为序列中的同一位置,运算之后的结果为0。


7.排序小结

ShellSort相当于InsertSort的升级,属插入排序类,
HeapSort相当于SelectionSort的升级,属选择排序类,
QuickSort相当于BubblSort的升级,属交换排序类。
复杂度分析:

排序算法 平均情况 最好情况 最坏情况 辅助空间 稳定性 BubbleSort O(n2) O(n2) O(n2) O(1) 稳定 SelectionSort O(n2) O(n2) O(n2) O(1) 稳定 InsertSort O(n2) O(n2) O(n2) O(1) 稳定 ShellSort O(nlogn)~O(n2) O(n1.3) O(n2) O(1) 不稳定 HeapSort O(nlogn) O(nlogn) O(nlogn) O(1) 不稳定 MergeSort O(nlogn) O(nlogn) O(nlogn) O(n) 稳定 QuickSort O(nlogn) O(nlogn) O(n2) O(logn)~O(n) 不稳定

8.code

my_sort.h

#ifndef MY_SORT_H#define MY_SORT_H#include <vector>namespace my_sort {    class MySort    {    public:        void BubbleSort0(std::vector<int> &i_arr);        void BubbleSort(std::vector<int> &i_arr);        void SelectSort(std::vector<int> &i_arr);        void InsertSort(std::vector<int> &i_arr);        void ShellSort(std::vector<int> &i_arr);        // Merge Sort        void MergeSort(std::vector<int> &i_arr);        void MSort(std::vector<int> &SR, int Left, int Right);        void Merge(std::vector<int> &SR, int Lpos, int mid, int Rpos);        //        void QuickSort(std::vector<int> &i_arr, int low, int high);    };    void my_swap(int &a, int &b);    void my_swap_ptr(int * a, int * b);    void my_swap_vec(std::vector<int> &i_arr, int i, int j);    void my_swap_val(int &a, int &b);}#endif // !MY_SORT_H

main.cpp

#include <iostream>#include <random>#include <functional>#include <time.h>#include "my_sort.h"#define print_arr(arr) \    for(auto &i:arr)\        cout << i<<" ";\    cout << endl;using namespace std;using namespace my_sort;int main(){    //int a = 1;    //int b = a;    //a ^= b;    //b ^= a;    //a ^= b;    //cout << a << " " << b << endl;    // 测试交换数组元素    int a[2] = { 1,3 };    a[1] ^= a[1];    a[1] ^= a[1];    a[1] ^= a[1];    std::default_random_engine generator(time(0));    std::uniform_int_distribution<int> dis(1, 100);    auto dice = std::bind(dis, generator);    const int NUM = 10;    vector<int> t_v;    for (int i = 0; i < NUM; i++)        t_v.emplace_back(dice());    print_arr(t_v);    my_sort::MySort sort;    //sort.BubbleSort(t_v);    //sort.SelectSort(t_v);    //sort.InsertSort(t_v);    //sort.ShellSort(t_v);    sort.MergeSort(t_v);    //sort.QuickSort(t_v, 0, t_v.size() - 1);    print_arr(t_v);    return 0;}
1 0
原创粉丝点击