快速排序(杂记)

快排在C语言中比较有用,但是在C++中用途不大,完全可以用sort函数代替(复杂度差不多)。
关于各种排序算法的复杂度推荐看一个视频来比较,
视频链接:https://www.bilibili.com/video/av14429343/
关于各种排序算法的简介推荐看一个网页来学习,
网页链接:https://mp.weixin.qq.com/s/qG4S3WjhGkaXM2B-P5M75w
OK,言归正传,现在就说快速排序。

还是先上主要代码

// 快速排序
void print(int a[], int n)//输出函数
{
   for(int j= 0; j<n; j++){
       cout<<a[j] <<"  ";
   }
   cout<<endl;
}
void swap(int *a, int *b)//交换函数
{
   int tmp = *a;
   *a = *b;
   *b = tmp;
}
int partition(int a[], int low, int high)//区间内排序
{
   int privotKey = a[low];                //基准元素
   while(low < high){                    //从表的两端交替地向中间扫描
       while(low < high  && a[high] >= privotKey)
           high--;  //从high 所指位置向前搜索,至多到low+1 位置。将比基准元素小的交换到低端
       swap(&a[low], &a[high]);
       while(low < high  && a[low] <= privotKey )
           low++;
       swap(&a[low], &a[high]);
   }
   print(a,10);
   return low;
}
void quickSort(int a[], int low, int high)//区间划分
{
   if(low < high){
       int privotLoc = partition(a,  low,  high);  //将表一分为二
   quickSort(a,  low,  privotLoc -1);      //递归对低子表递归排序
   quickSort(a,   privotLoc + 1, high);    //递归对高子表递归排序
   }
}

从最简单的开始。两个数如何排序?交换位置就可以了;三个数如何排序?一其中一个为基点,于其他的数进行比较就OK了。那么,我们可以把所有的排序归拢到简单问题吗?这种思想在计算机里被称为分治法(超有用)。

简述分治法,解释起来就是 “大事化小,小事化了” ,把复杂的问题变成简单的问题,又点像递归,但是递归是有规律可循的,分治没有。分治只需要简单问题的解法,不需要知道简单问题到复杂问题的规律。

分治在快速排序中的应用

分治需要大事化小,小事化了,所以需要分好区块。想想对于每个数来说排序是什么?就是小的在我左边,大的在我右边。所以我们先把第一个数(arr[0])放到该去的位置,然后我们就会发现,数组已经被分成两个区了,一个比arr[0]小,一个比arr[0]大,以此类推,分别处理两个区直到每个区只有三个数,然后用处理简单问题的方式处理。

展示一下完整代码

// 快速排序
#include<iostream>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<stack>
#include<queue>
#include<iomanip>
#include<map>
#include<set>
#include<functional>
using namespace std;
void print(int a[], int n)
{
    for(int j= 0; j<n; j++){
        cout<<a[j] <<"  ";
    }
    cout<<endl;
}
void swap(int *a, int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}
int partition(int a[], int low, int high)
{
    int privotKey = a[low];                //基准元素
    while(low < high){                    //从表的两端交替地向中间扫描
        while(low < high  && a[high] >= privotKey)
            high--;  //从high 所指位置向前搜索,至多到low+1 位置。将比基准元素小的交换到低端
        swap(&a[low], &a[high]);
        while(low < high  && a[low] <= privotKey )
            low++;
        swap(&a[low], &a[high]);
    }
    print(a,10);
    return low;
}
void quickSort(int a[], int low, int high)
{
    if(low < high){
        int privotLoc = partition(a,  low,  high);  //将表一分为二
    quickSort(a,  low,  privotLoc -1);      //递归对低子表递归排序
    quickSort(a,   privotLoc + 1, high);    //递归对高子表递归排序
    }
}
int main()
{
    int a[10] = {3,1,5,7,2,4,9,6,10,8};
    cout<<"初始值:";
    print(a,10);
    quickSort(a,0,9);
    cout<<"结果:";
    print(a,10);
}

总结

快排的实用性不大,但是思想是很好的,建议学习时笔推一遍代码,体会一下分区的感觉和方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值