快速排序算法 (c/c++)

快速排序

      • QuickSort:
      • Code_1(中间元素为基准)
      • Code_1示例结果
      • Code_2(第一元素为基准)
      • Code_2示例结果
      • 算法分析

QuickSort:

  • 通过一趟排序将要排序的数据分隔成独立的两部分,其中一部分的所有数据都要比另一部分数据小,然后按此方法对这两部分分别再进行快速排序,整个排序过程可以递归进行,以此达到数据的有序。
        ㅤㅤㅤㅤㅤㅤ
  • 快速排序算法通过多次比较和交换实现排序,流程如下
    首先设定一个分界值,将数据分成左右两部分
    将大于等于分界值的数据集中到数组右边,将小于等于分界值的数据集中到数组左边,
    然后左边和右边分别再各自取分界值进行类似处理
    重复上述操作,通过递归将左边排好序后,再递归右边,当左右两个部分各个数据排序完成后,整个数据的排序也就完成。

Code_1(中间元素为基准)

void QuickSort(int *arr ,int end,int start,int length){   //初始start = 0 end = length-1 
	//传入length值是为了方便打印每趟排序序列
    int i = start; // i=0 数据第一个元素
    int j = end;   // j=length-1 数据最后一个元素
    int mid = arr[(start+end)/2];  //中间位置值为基准
    do{
        while(arr[i]<mid)	//循环找到前序列大于基准的值
            ++i;
        while(arr[j]>mid)	//循环找到后序列小于基准的值
            --j;
        if(i<=j){
            swap(arr[i],arr[j]);	//交换两值
            ++i;
            --j;
        }
    }while(i<=j);
    
    //打印每趟排序结果
    cout<<"每趟排序序列:";
    for(int k = 0;k<length;k++)
        cout<<setw(2)<<setfill('0')<<arr[k]<<" ";
    cout<<endl<<"-----------------------"<<endl;
    
    if(i<end)
        QuickSort(arr,end,i,length);	//后序列递归
    if(start<j)
        QuickSort(arr,j,start,length);	//前序列递归
}

Code_1示例结果

Before Sort:  01 05 06 03 04 02 07
-----------------------
-----------------------
每趟排序序列:01 02 03 06 04 05 07
-----------------------
每趟排序序列:01 02 03 04 06 05 07
-----------------------
每趟排序序列:01 02 03 04 05 06 07
-----------------------
每趟排序序列:01 02 03 04 05 06 07
-----------------------
每趟排序序列:01 02 03 04 05 06 07
-----------------------
-----------------------
After  Sort:  01 02 03 04 05 06 07

Code_2(第一元素为基准)

分治策略

  • 分解arr[s…t]为arr[s…i-1]和arr[i+1…t]其中i为划分基准
  • 求解子问题:若子序列长度为0或1,则他是有序的,直接返回,否则递归求解各个子问题
  • 合并:由于整个序列存放在数组arr中,排序过程就地进行,合并步骤不需要任何操作

快速排序算法 (c/c++)_第1张图片

int Partition(int *arr,int s,int t){    //划分算法
    int i = s,j = t;
    int tmp = arr[s];   //用第一元素作为基准
    while(i!=j){    //从序列两端交替向中间扫描,直到i = j为止
        while(j>i&&arr[j]>=tmp)
            --j;    //从右向左扫描,找到第1个关键字小于tmp的arr[j]
        arr[i] = arr[j];    //将arr[j]前移到arr[i]的位置
        while(i<j&&arr[i]<tmp)
            ++i;    //从左向右扫描,找到第1个关键字大于tmp的arr[i]
        arr[j] = arr[i];    //将arr[i]后移到arr[j]的位置
    }
    arr[i] = tmp;   //放入基准值
    return i;   //返回基准值所在数组下标
}

void QuickSort(int* arr ,int s,int t,int length){	//传入length是为了打印每趟序列
    //对arr[s..t]进行递增排序
    if(s<t){    //序列至少存在2个元素
        int i = Partition(arr,s,t);

        //打印每趟排序结果
        cout<<"每趟排序序列:";
        for(int k = 0;k<length;k++)
            cout<<setw(2)<<setfill('0')<<arr[k]<<" ";
        cout<<endl<<"-----------------------"<<endl;

        QuickSort(arr,s,i-1,length);   //对左子序列递归排序
        QuickSort(arr,i+1,t,length);   //对左子序列递归排序
    }
}

Code_2示例结果

Before Sort:  02 05 01 07 10 06 09 04 03 08
-----------------------
-----------------------
每趟排序序列:01 02 05 07 10 06 09 04 03 08
-----------------------
每趟排序序列:01 02 03 04 05 06 09 10 07 08
-----------------------
每趟排序序列:01 02 03 04 05 06 09 10 07 08
-----------------------
每趟排序序列:01 02 03 04 05 06 09 10 07 08
-----------------------
每趟排序序列:01 02 03 04 05 06 08 07 09 10
-----------------------
每趟排序序列:01 02 03 04 05 06 07 08 09 10
-----------------------
-----------------------
After  Sort:  01 02 03 04 05 06 07 08 09 10

算法分析

  • 时间复杂度:
    最好O(n2)
    最坏O(nlogn)
    平均O(nlogn)
  • 空间复杂度:O(logn)
  • 排序方式:内部排序
  • 稳定性:不稳定
  • ——————END-2022-01-05——————
  • 个人学习笔记,如有纰漏,敬请指正。
  • 感谢您的阅读。

你可能感兴趣的:(算法,排序算法,c语言,c++)