分治法之快速排序
前言
快速排序的时间复杂度为O(nlogn)。有时候oj的时候出现超时,可以考虑使用快速排序,但是快速排序是一个不稳定的排序算法。一、分治算法的思想
分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
二、快速排序的详解
1.快速排序的思想
- 哨兵i和哨兵j分别从数组的两端出发。
- 哨兵j一步步的向左寻找,当出现的数据小于基准数时停下来。(注意,因为基准数设置在最左边,所以在右边的哨兵j先开始出发。)
- 这时哨兵i从右边开始出发,一步一步的找,当出现的数大于基准数时停下来。
- 这时交换这时哨兵i和哨兵j所指向的两个数。然后再继续步骤2和步骤3.
- 当哨兵i和哨兵j相遇时,第一轮“探测”结束。而此时他们相遇的位置就是基数应该在的位置。这句话可以用来用分治法求解K大(小)问题。
- 然后将整个数组序列以刚才寻找到的基准数的位置一分为二形成两个序列,重复步骤2,3,4,5,6。这里便是分治法的思想
2.快速排序的步骤图解(图来自于啊哈算法)
下面的这个图就很好的说明了分治在这个问题中的应用。
从上面的图中我们可以知道,每当两个哨兵相遇时,即i==j时,此时就找到了基准数的位置。
三.程序代码
#include <stdio.h>
int a[10000];
void quickSort(int left,int right)
{
int i,j,temp;
i=left;
j=right;
temp=a[i];
if(i>j) /*递归出口,当区间长度为1时,我们默认这个区间有序*/
return ;
while(i<j)
{
while(i<j&&a[j]>=temp)
j--;
while(i<j&&a[i]<=temp)
i++;
if(i<j)
{
int t=a[i];
a[i]=a[j];
a[j]=t;
}
}
/*将基数复位*/
a[left]=a[i];
a[i]=temp;
/*分治:两边分别不断地划分小区间*/
quickSort(left,i-1);
quickSort(i+1,right);
}
int main()
{
int n,i;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
quickSort(0,n-1);
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}