快排在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);
}
总结
快排的实用性不大,但是思想是很好的,建议学习时笔推一遍代码,体会一下分区的感觉和方法。