zoukankan      html  css  js  c++  java
  • 数据结构-排序-快排

                    快速排序

      首先快速排序步骤:

    • 首先选择轴值
    • 把待排序内容分为两部分,左边为小于或者等于轴值,右边为大于轴值
    • 然后对左右重复上面步骤直到整个序列有序
    • 直接上代码这里先写一次划分的代码
    • 这里的一次划分是那第一个数字为轴值,我们也可以用最后一个或者中间的。
    • #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();
    • 我们运行程序看下
    • 这是不停的对左侧左侧左侧的递归

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

        

        

  • 相关阅读:
    STM32之滴答定时器
    串口--USART1
    风扇--PWM控制
    触摸屏移植Emwin
    emwin--GUI
    extern
    STM32之定时器时间计算
    stm32之定时器
    stm32之PWM
    stm32之SPI
  • 原文地址:https://www.cnblogs.com/DJC-BLOG/p/9069400.html
Copyright © 2011-2022 走看看