内排序算法总结——快速排序
来源:互联网 发布:软件测试工程师面试题 编辑:程序博客网 时间:2024/05/16 17:39
快速排序
快速排序是一种在含n个数的输入数组上最坏情况运行时间为O(n2)的算法,平均性能的期望运行时间为O(nlgn),且O(nlgn)记号中隐含的常数因子很小。另外,它还能够进行原地置换排序。
快速排序是基于分治模式上的,分治过程三个步骤:
1.分解:把数组A[p...r]分成两个非空子数组A[p...q]和A[q+1...r],使得A[p...q]的每个元素都小于等于A[q+1...r]中的元素,下标q也在这个划分过程中进行计算。
2.解决:通过递归调用快速排序对子数组A[p...q]和A[q+1...r]排序。
3.合并:因为两个子数组是原地排序的,不需要将它们合并,整个数组A[p...r]已排序。
过程如下:
QuickSort(A,p,r)
{
if p<r
then q = Partition(A,p,r);
QuickSort(A,p,q);
QuickSort(A,q+1,r);
}
快速排序算法的关键是Partition过程,它对子数组A[p...r]进行划分,并得到划分的界限q:
Partition(A,p,r)
{
x = A[p];
i = p-1;
j = r+1;
while TRUE
do repeat j = j-1
until A[j] <= x
repeat i = i+1
until A[i] >= x
if i<j
then swap (A[i] , A [j])
else return j
}
代码如下:
...{
int t = a;
a = b;
b = t;
}
int Partition(int *A, int left, int right)
...{
int x = A[left];
int i = left - 1;
int j = right;
while(1)
...{
while(A[j]>x)
--j;
while(A[i]<x)
++i;
if(i<j)
Swap(A[i],A[j]);
else return j;
}
}
void QuickSort(int* A,int left, int right)
...{
if(left < right)
...{
int q = Partition(A,left,right);
QuickSort(A,left,q);
QuickSort(A,q+1,right);
}
}
void PrintArray(int data[], int n)
...{
int i;
for(i = 0; i < n; i++)
...{
printf("%d ", data[i]);
}
printf(" ");
}
void main()
...{
int A[] = ...{4, 1, 44, -12, 5, 125, 30};
QuickSort(A,0,6);
PrintArray(A,7);
}
当数组已经排序好(正序)时,快速排序的的时间代价是O(n2),而这对插入排序只要O(n)的时间
因为此时把数组划分为两部分,分别含1个和n-1个的数组,而快速排序的最佳情况是两个子数组大小都是n/2
改进(随机化版本):当数组还没有被划分时,可将元素A[p]与A[p...r]中随机选出的一个元素交换。
只要把Partition函数开头加入随机化即可:
Randomized_Partition(A,p,r)
{
i = Random(p,r)
swap (A[p],A[i])
return Partition(A,p,r)
}
相应地,在QuickSort里调用Randomized_Partition(A,p,r)
代码如下:
...{
int t = a;
a = b;
b = t;
}
int Partition(int *A, int left, int right)
...{
int x = A[left];
int i = left - 1;
int j = right;
while(1)
...{
while(A[j]>x)
--j;
while(A[i]<x)
++i;
if(i<j)
Swap(A[i],A[j]);
else return j;
}
}
int new_random(int min, int max)
...{
return (min + (int)(((float)rand()/RAND_MAX)*(max - min)));
}
int Randomized_Partition(int *A, int left, int right)
...{
int i = new_random(left, right);
Swap(A[i], A[right]);
return Partition(A, left, right);
}
void Randomized_QuickSort(int* A,int left, int right)
...{
if(left < right)
...{
int q = Randomized_Partition(A,left,right);
QuickSort(A,left,q);
QuickSort(A,q+1,right);
}
}
void PrintArray(int data[], int n)
...{
int i;
for(i = 0; i < n; i++)
...{
printf("%d ", data[i]);
}
printf(" ");
}
void main()
...{
int A[] = ...{4, 1, 44, -12, 5, 125, 30};
Randomized_QuickSort(A,0,6);
PrintArray(A,7);
}
另外,还有一个方案,是在待排序的数组里随机选三个元素,取值为第二大的那个作为基准数也可
- 内排序算法总结——快速排序
- 内排序算法总结——插入排序
- 内排序算法总结——选择排序
- 内排序算法总结——冒泡排序
- 内排序算法总结——二分法插入排序
- 内排序算法总结——希尔排序
- 排序算法总结【内排序】
- 排序算法—快速排序
- 排序算法—快速排序
- 排序算法总结(6)——快速排序
- 排序算法总结----快速排序
- 快速排序算法总结
- 快速排序算法总结
- 【排序算法】内排序算法总结
- 【算法总结】快速排序算法
- 数据结构算法总结-内排序
- 排序算法总结(二)——快速排序、归并排序
- 排序算法———快速排序
- 中秋贺卡
- PHP 会话 (Session) 使用入门
- PHP网站漏洞的相关总结
- 关于PHP--session的问题集锦解决方案
- Opera书签的位置
- 内排序算法总结——快速排序
- 脚本引擎初步研究
- Sniffer Pro的基本使用和实例
- Linux一贴通
- 博客周刊深度阅读之“Ruby与Java争锋”
- A4J 用户指南
- 整合动易2006、动网7.1SP1、Oblog 3.13详细设置说明
- 现在的我
- xajax中文手册(HonestQiao第一版,FlyingHail修改版)