分治算法之快速排序
上一篇:分治算法之二分查找【含例题】
快速排序
概述
快速排序是对冒泡排序的改进,和冒泡排序一样,同属于交换排序。
其主要包括
(1) Divide: 分割成两个子数组
(2) Conquer: 递归处理两个子数组
(3) Combine: 连接在一起
核心思想
- 数据分区:一部分比另一部分小
- 递归排序:递归处理两部分
实例分析
伪代码
分区函数 Partition(A, p, q)
快速排序函数:QuickSort(A, p ,q)
时间复杂度
最坏情况(划分为1和n-1两段):
O(n^2)
最好情况(划分成两段都为n/2):
O(nlogn)
一般情况(按照一定的比例划分,例如1/10 : 9/10):
O(nlogn)
平均时间复杂度:
T(n) = O(nlogn)
核心代码
main函数
int main()
{
int a[] = {6, 10, 13, 5, 8, 3, 2, 11};
quickSort(a,0,7);
for(int i=0; i<=7; i++)
{
printf("%d ",a[i]);
}
return 0;
}
快速排序函数
void quickSort(int a[], int p, int q)
{
if(p < q)
{
int r = partition(a, p, q);
quickSort(a, p, r-1);
quickSort(a, r+1, q);
}
}
分区函数
int partition(int a[], int p, int q)
{
int x = a[p];
int i = p, j;
for(j = p + 1;j <= q; j++)
{
if(a[j]<=x)
{
i++;
swap(a,i,j);
}
}
swap(a,p,i);
return i;
}
交换函数
int swap(int a[], int i, int j)
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
算法改进——随机化快速排序
当分区出现最坏情况(划分为1和n-1两段),时间复杂度为O(n^2),显然这种情况是不快速排序想要的。接下来我们就看随机化快速排序。
- 快速排序算法的性能取决于
划分的对称性
- 通过修改算法Partition,可以设计出
采用随机选择策略
的快速排序算法- 在A[p…q]中
随机选出一个元素作为划分基准
随机化快速排序的时间复杂度为:T(n) = O(nlogn)
产生随机数函数
-
已知rand()函数可以随机生成一个非负整数
-
产生[a,b]之间的随机非负整数:rand%(b-a+1)+a
//rand()函数的用法。
/* 输出 0 到 49 之间的 5 个随机数 */
for( i = 0 ; i < 5 ; i++ ) {
printf("%d\n", rand() % 50);
}
随机化快速排序函数
void randomizedQuickSort(int a[], int p, int q)
{
if(p < q)
{
int r = randomizedPartition(a, p, q);
randomizedQuickSort(a, p, r-1);
randomizedQuickSort(a, r+1, q);
}
}
分区函数
int randomizedPartition(int a[], int p, int q)
{
int r = random(p,q);
swap(a,p,r);
int i = partition(a, p, q);
return i;
}
产生随机数
int random(int p, int q)
{
return rand()%(q-p+1) + p;
}
如有错误,恳请指正
最后,如果这篇文章对你有帮助,欢迎一键三连
要么努力,要么放弃