版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xnh_565175944/article/details/82809504
快速排序是分治算法一种排序。
快速排序有三个步骤:
(1).分解: 将数组num分为三段,以第一个数为基准,划分为三段,将比第一个数大的全部放在右边,将比第一个数小的全部放在左边。
(2). 递归求解: 对已经分成的三段,左边和右边进行分解排序。
(3).合并: 当分解到3个数或者两个数的时候,就可以局部的排好顺序。而每个局部的排序,将组合形成整个数组的排序。
swap 用来交换值,没什么可说的
void swap(int num[],int i,int j) //用来交换i与j的值
{
int t = num[i];
num[i] = num[j];
num[j] = t;
}
partition(int num[],int p,int r) 用来将数组从p-r 位置的数进行划分,并给出基准数的下标
int partition(int num[],int p,int r)
{
int x = num[p]; //首先我们要获取第一个元素的值
int i = p,j = r + 1;
//将<x的元素交换到左边区域 将>x的元素交换到右边区域
while(true)
{
//寻找首位置后面大于x的数的位置,还需注意 i不可以超过r
while(num[++i] < x && i<r);
//寻找尾位置前面小于x的数的位置,这里不需要规定界限,因为如果都大于的话,那就是排好序的数组 在下一步会自动跳出
while(num[--j] > x);
if(i>=j) break;
//交换<x 和>x数
swap(num,i,j);
}
num[p] = num[j]; //跳出循环后,我们需要把x放在它应该在的位置
num[j] = x;
return j;
}
qSort(int num[], int p,int r) 用来排序,对于n个元素的数组,范围是[0, n-1]
void qSort(int num[],int p,int r)
{
if(p<r)
{
// 我们根据partition函数返回的下标值。我们可以区分左右区域,从而进行再一次的排序
int q = partition(num,p,r);
//对左边进行排序
qSort(num,p,q-1);
//对右边进行排序
qSort(num,q+1,r);
}
}
算法复杂度分析:
考虑算法复杂度必须要考虑最坏情况和最优情况.
最坏情况:
在每次划分区域的时候,都只能划分出n-1个元素和1个元素,所以要进行n次递归。因为partition的计算时间是O(n)。所以该算法最坏情况的时间复杂度是O(n²)(条件是n>1,n为1时 只递归1次为O(1))
最优情况:
在每次划分区域的时候,都恰好平分两个区域,所以我们只需要递归log₂n次即可,8个数(3次)..... 由于每层递归的总时间是O(n),所以最优情况下的时间复杂度是O(n*log₂n)。
代码:
#include <iostream>
using namespace std;
void swap(int num[],int i,int j)
{
int t = num[i];
num[i] = num[j];
num[j] = t;
}
int partition(int num[],int p,int r)
{
int x = num[p];
int i = p,j = r + 1;
while(true)
{
while(num[++i] < x && i<r);
while(num[--j] > x);
if(i>=j) break;
swap(num,i,j);
}
num[p] = num[j];
num[j] = x;
return j;
}
void qSort(int num[],int p,int r)
{
if(p<r)
{
int q = partition(num,p,r);
qSort(num,p,q-1);
qSort(num,q+1,r);
}
}
int main()
{
int num[10] = {7,2,1,3,5,8,9,6,1,3};
qSort(num,0,9);
for(int i=0;i<10;i++)
{
printf("%d ",num[i]);
}
return 0;
}