zoukankan      html  css  js  c++  java
  • 快速排序

    快速排序:使用的是分治思想 (归并排序也是);

    (1)选一个元素M作为基准数。

    (2)把小于等于M的元素放在数组的左边,大于M的元素放在数组右边;这是M的位置已是正确的,不再改变。

    (3)对M左边、右边的的数组分别使用(1)(2),知道数组中只有一个元素。

    性能:

    最坏时间复杂度是O(n2),平均时间复杂度是(nlogn),最好时间复杂度是(nlogn),是一种不稳定排序。

    快速排序的三步分治过程:分解,解决,合并。由于子数组是原址排序,所以不需要合并操作。

    注:在代码中,p r 均是数组下标,p 是首元素的下标, r 是最后一个元素的下标

    QuickSort( A, p, r)

         if   p < r 

             q = Partition( A, p, r ) 

             QuickSort( A, p, q-1)

             QuickSort( A, q+1, r)

    算法的关键是 Partition 过程,他实现了对子数组 A[p, r] 的原址重排

    Partition ( A, p, r ) 

          x = A[ r ]

          i = p - 1

          for  j  =  p  to  r -1

                if  A[ j ]  <=  x

                    i = i + 1 

                   exchange A[ i ]  with A[ j] 

         exchange A[ i+1] with A[ r ]

         return i + 1

    快速排序的随机化版本(使得算法对所有的输入都有较好的期望性能),新的划分程序中,只在真正进行划分前进行一次交换,QuickSort( A, p, r)代码不变;

    RandomPartition( A, p, r)

             i = Random(p, r)

            exchance A[ r ]  with A[ i ]

            return Partition( A, p, r)

    代码:

    #include<iostream>
    #include<vector>
    using namespace std;
    template<class T>
    int Partition(vector<T>&A, int p, int r)    // p 和 r 均为数组段的下标,p是数组首元素下标,r是数组最后一个元素下标
    {
        T x = A[r];
        int  flag = p - 1;
        for (int j = p; j <= r-1; j++)    //遍历数组中的元素
        {
            if (A[j] <= x)                // 将数组中小于 A[r]的元素移到数组的左边
            {
                flag = flag + 1;
                T temp = A[flag];
                A[flag] = A[j];
                A[j] = temp;
            }
        }
        T tem = A[flag + 1];
        A[flag + 1] = A[r];
        A[r] = tem;
        return flag + 1;
    }
    template<class T>
    void QuickSort(vector<T>& Arry,int p,int r)
    {
        if (p <= r-1)
        {
            int q = Partition(Arry,p,r); //返回的元素位置已经被正确分类,即下面函数参数有 q-1,q+1,
            for (int i = 0; i <= r; i++)
                cout << Arry[i] << " ";
            cout << endl;
            QuickSort(Arry,p,q-1);         //这里也是分治的思想,q位置的元素位置已正确,只需对(q,q-1)与(q+1,r)排序
            QuickSort(Arry, q+1,r);
        }
    }

    测试代码:

    int main()
    {
        vector<int> arry= { 210, 12,19, 4, 7, 10, 15,21, 41, 51, 61, 81, 71, 91, 100,310,250,630,0,17};
        for (int i = 0; i < 20; i++)
            cout << arry[i] << " ";
        cout << endl;
        QuickSort<int>(arry, 0, 19);
        for (int i = 0; i < 20; i++)
            cout << arry[i] << " ";
        cout << endl;
        cout << "BigThink" << endl;
        system("pause");
        return 0;
    }
    View Code

    vector 容器做函数参数:

    void Example( vector<int> vec);

    void Example( vector<int> *vec);

    void Example( const vector<int> * vec);   //在函数内不能改变 vec指向的对象

    void Example( vector<int>& vec);

    void Example( const  vector<int>& vec);    // 在函数内不能改变 vec 对象

  • 相关阅读:
    Visual Studio 2019 使用 Web Deploy 发布远程站点到IIS服务器
    postman下载地址
    ASP.NET Core开发-Docker部署运行
    C# ffmpeg 视频处理格式转换具体案例
    C# ffmpeg 视频处理格式转换和添加水印
    C# ffmpeg 视频处理
    Tomcat 安装与配置
    Maven 快速入门
    Jenkins 快速搭建
    Google SRE 读书笔记 扒一扒SRE用的那些工具
  • 原文地址:https://www.cnblogs.com/hello-gogo/p/7098179.html
Copyright © 2011-2022 走看看