优化一个算法的最根本的原理就是减少算法的基本操作。
分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
于是,在快速排序中,我们通过分割数组的思路来将大问题分割成小规模的问题,与二分搜索法类似的是,在二分法
中,我们需要进行的操作是搜索,是在已经排好序的基础上通过一分为二来减少搜索范围,降低时间复杂度,二分搜
索中通过寻找中位数,将数组分为左右两边,通过与中位数的比较确定待查找数所在的范围,即,我们在判断是否中
位数与待查找数的大小的同时,还利用判断的结果,将搜寻的范围缩小,这就与最基本的遍历法中仅仅比较是否相等
有了很大的差距,换句话讲,就是在二分搜索中,我们通过一次比较进行了两种操作,而在传统的遍历中,我们通过
一次比较仅仅只进行一种操作。于是,在排序中,我们是否也可以考虑这种思路。传统的冒泡排序中,我们仅仅在一
个数与其他数的比较时确定了一个数的位置(这里写的有点难理解的感觉),我们在进行比较的同时是否能仿照二分
搜索法一般,比较的同时缩小排序的范围,即我们通过选取一个基准元素将带排序数组划分为两个数组,在基准元素
与数组元素进行比较的同时,将大于基准元素的数放到数组的右侧,小于基准的数放到数组左侧,在通过同样的思路
对被划分而成两个个子问题进行相同的操作,直到最终子问题的大小等于3。
下面就是相关的实现步骤:
1.分解:以a[p]为基准元素将a[p:r]划分为三段a[p:q-1],a[q+1:r]使得a[p:q-1]中任何元素小于等于a[q],a[q+1]中任何元素
大于等于a[q]下标q在划分过程中确定
2.递归求解:通过递归调用快速排序算法,分别对a[p:q-1]和a[q+1]进行排序
3:合并:由于对a[p:q-1]和a[q+1:r]的排序是就地进行的所以a[p:q-1]和a[q+1:r]都已排好的序后不需要执行任何计算,
就已排好序.
void Algorithm::qSort(int a[],int left,int right)
{
if(left<right)
{
int middle=partition(a,left,right);
qSort(a,left,middle-1);
qSort(a,middle+1,right);
}
}
int Algorithm::partition(int a[],int left,int right)
{
int first=left+1;
int last=right;
int number=a[left];
int i=0;
while(true)
{
while(a[first]<number&&first<=right)
{
first++;
}
while(a[last]>number)
{
last--;
}
if(first>=last)
{
break;
}
else
{
int temp=0;
temp=a[last];
a[last]=a[first];
a[first]=temp;
}
}
a[left]=a[last];
a[last]=number;
return last;
}