数据结构-排序-快排

Posted 邓佳程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构-排序-快排相关的知识,希望对你有一定的参考价值。

                快速排序

  首先快速排序步骤:

  • 首先选择轴值
  • 把待排序内容分为两部分,左边为小于或者等于轴值,右边为大于轴值
  • 然后对左右重复上面步骤直到整个序列有序
  • 直接上代码这里先写一次划分的代码
  • 这里的一次划分是那第一个数字为轴值,我们也可以用最后一个或者中间的。
  • #include<iostream>
    #include<vector>
    using namespace std;
    //不含暂存单元的数组v1
    int temp1[]={59,20,17,36,98,14,23,83,13,28};
    vector<int>  v1(begin(temp1),end(temp1));
    //打印数组
    inline void  printV(const vector<int> &v)
    {
        for(auto a:v)
            cout<<a<<" ";
        cout<<endl;
    }
    //第一次划分
    //快速排序第一次划分
    int Partition(vector<int> &v,int first,int end)
    {
        int i=first;
        int j=end;
        printV(v);
        cout<<"此时i="<<i<<"  此时j="<<j<<"  ";
        while(i<j)
        {
            while(i<j&&v[i]<v[j])
            {j--;
            cout<<"此时i="<<i<<"  此时j="<<j<<endl;}
            if(i<j)//假如i<j  交换ij
            {
                cout<<"交换"<<"  ";
                int temp=v[j];
                v[j]=v[i];
                v[i]=temp;
                i++;
                printV(v);
                cout<<"此时i="<<i<<"  此时j="<<j<<"  ";
            }
            cout<<endl;
            while(i<j&&v[i]<=v[j])
               { i++;
                cout<<"此时i="<<i<<"  此时j="<<j<<endl;}
            if(i<j)
            {
                cout<<"交换"<<"  ";
                int temp=v[j];
                v[j]=v[i];
                v[i]=temp;
                j--;
                printV(v);
                cout<<"此时i="<<i<<"  此时j="<<j<<"  ";
            }
        }
        printV(v);
        return i;
    }
    //这里我们先直接调用一次划分理解下如何划分的
    int main(int argc, char *argv[])
    {
        Partition(v1,0,v1.size()-1);
        return 0;
    }

    然后上运行截图分析

  

  • 首先取59为轴值,然后因为要左边比59小,右边比59大
  • 59与28比较发现59大于28 交换
  • 交换后继续遍历左侧。于是i++,遍历到98发现59小了,交换
  • 然后此时左边必然都小于59,但是右边不确定,开始遍历J
  • J=8发现13小于59然后再次交换,然后右边必然大于59,左边不确定,继续遍历i
  • i=7时59<83交换
  • 这是i=j不满足i<j的条件跳出循环
  • 此时以59为轴值,左边都小于59右边都大于

 

  接下来就是完整的包含递归的快排了

  先上代码

#include<iostream>
#include<vector>
using namespace std;
//不含暂存单元的数组v1
int temp1[]={59,20,17,36,98,14,23,83,13,28};
vector<int>  v1(begin(temp1),end(temp1));
//打印数组
inline void  printV(const vector<int> &v)
{
    for(auto a:v)
        cout<<a<<" ";
    cout<<endl;
}
//快速排序一次划分
int Partition(vector<int> &v,int first,int end)
{
    int i=first;
    int j=end;
    printV(v);
    cout<<"此时i="<<i<<"  此时j="<<j<<"  ";
    while(i<j)
    {
        while(i<j&&v[i]<v[j])
        {j--;
        cout<<"此时i="<<i<<"  此时j="<<j<<endl;}
        if(i<j)//假如i<j  交换ij
        {
            cout<<"交换"<<"  ";
            int temp=v[j];
            v[j]=v[i];
            v[i]=temp;
            i++;
            printV(v);
            cout<<"此时i="<<i<<"  此时j="<<j<<"  ";
        }
        cout<<endl;
        while(i<j&&v[i]<=v[j])
           { i++;
            cout<<"此时i="<<i<<"  此时j="<<j<<endl;}
        if(i<j)
        {
            cout<<"交换"<<"  ";
            int temp=v[j];
            v[j]=v[i];
            v[i]=temp;
            j--;
            printV(v);
            cout<<"此时i="<<i<<"  此时j="<<j<<"  ";
        }
    }
    printV(v);
    cout<<"一次part结束"<<endl;
    return i;
}

//快排
void QuickSort(vector<int> &v,int first,int end)
{
    if(first<end)
    {
        int pivot=Partition(v,first,end);
        QuickSort(v,first,pivot-1);;
        QuickSort(v,pivot+1,end);
    }
}


int main(int argc, char *argv[])
{
    QuickSort(v1,0,v1.size()-1);
    return 0;
}
  • 我们先看下QuickSort函数,当partition函数返回i,i就是刚才59的位置
  • 我们此时以59为分界线,分为左右两侧,分别对左右继续划分,直到所有的每次递归first-end的范围的数量=1则跳出
  • 看下下面的递归第一次partition调用结束后,QuickSort后面的参数是v,,first,i的位置-1  比如第一次递归就是  v[0]到59的位置减1
  • 然后后面的就是59+1到v.end();
  • 我们运行程序看下
  • 这是不停的对左侧左侧左侧的递归

  • 这是不停的对右侧右侧递归。由于右侧数字很少,递归也很快结束了。

    

    

以上是关于数据结构-排序-快排的主要内容,如果未能解决你的问题,请参考以下文章

快速排序(快排)

排序算法之冒泡和快排

代码与算法集锦-归并排序+树状数组+快排+深度优先搜索+01背包(动态规划)

8种面试经典!排序详解--选择,插入,希尔,冒泡,堆排,3种快排,快排非递归,归并,归并非递归,计数(图+C语言代码+时间复杂度)

快速排序(经典快排以及随机快排)

七大排序算法(插排,希尔,选择排序,堆排,冒泡,快排,归并)--图文详解