快速排序
一.挖坊填补法
先选择一个标准值,将它取出,我们把它看做一个坑。
我们选择最低的一位作为标准值。
从后向前遍历,(高指针向低指针遍历)找到比这个标准值小的值就放入坑中,这时就产生了一个新的坑。
再从前向后遍历,(低指针向高指针遍历)找到比标准值大的值则放入坑中,这时产生了一个新的坑。
再从后向前遍历(高指针向低指针遍历)。。。。。
当高低指针相遇的时候,将标准值放入。这时标准值得左边都是比标准值小的,标准值得后面都是比标准值大的。
将左边,和右边看成独立数组,重复以上步骤。(递归实现)
代码:
int FindStandard(int *arr,int low,int high)
{
int num = arr[low];
while(low < high)
{
//从后向前找
while(low < high)
{
if(arr[high] < num)
{
arr[low] = arr[high];
break;
}
high--;
}
//从前向后找
while(low < high)
{
if(arr[low] > num)
{
arr[high] = arr[low];
break;
}
low++;
}
}
arr[low] = num;
return low;
}
void QuickSort(int* arr,int low, int high)
{
if(arr == NULL || low >= high)
return;
int Standard = FindStandard(arr,low,high);
//以标准值为界限分为左半部分和右半部分,再分别重复以上步骤
QuickSort(arr,low,Standard-1);
QuickSort(arr,Standard+1,high);
}
优化1:如何提高系统效率?while循环嵌套的效率比较低,改用for,从一个方向遍历。则有了第二种方法:区间分割法。
二. 区间分割法
思路:将最后一个数先作为标准值,然后从低位向高位遍历,比较。设置一个标记,为比标准值小的数。
如果此数比标准值小,看是否为标记的下一个,是则标记++;不是则与标记的下一个值交换。这样可以保证从最低位到标记都是比标准值小的。
最后将最后一位的值也就是标准值与标记的下一个交换。
这样标准值前面的都是比标准值小的,标准值后面的都是标准值大的。标准值位置即排好序的位置。
将标准值左右分为两个数组。左右分别调用此
代码:
int FindStandard(int* arr,int low,int high)
{
int small = low-1;//标记位
for(low;low < high;low++)
{
if(arr[low] < arr[high])
{
//如果该比标准值小的值不是标记的下一位,那么标记的下一位与该值交换。是则small++
//所以可以先small++,如果不是标记的下一位则交换,是则不执行。
if( ++small != low )
{
arr[small] = arr[small]^arr[low];
arr[low] = arr[small]^arr[low];
arr[small] = arr[small]^arr[low];
}
}
}
//如果标准值就是最后一位则不用交换
if(++small != high)
{
arr[small] = arr[small]^arr[high];
arr[high] = arr[small]^arr[high];
arr[small] = arr[small]^arr[high];
}
return small;
}
void QuickSort(int*arr,int low,int high)
{
if(arr == NULL || low >= high )
return;
int standard = FindStandard(arr,low,high);
QuickSort(arr,low,standard-1);
QuickSort(arr,standard+1,high);
}
优化2:如何避免标准值是最大值或最小值? 因为我们的思路是,找到一个标准值将它分为左右两个部分,如果标准是最大值,那么没有达到目的,并且邹静FindStandard的循环没有做事。 所以为了避免这种偶然事件发生我们可以选3个数,最低位,最高位和中间位。在他们3个中选择一个中间位,这样绝不可能是最大值或者最小值了。为什么不用随机数? 随机数的种子根据时间生成随机数,生成的3个数相同的概率比较大。
优化3:如何避免系统异常? 因为代码中用到了递归,系统自动调用,压入栈中,这是我们不能控制的,可能发生异常。
优化4:数据过少怎么办? 如果数据过少,我们就没有必要使用快排了,使用插入排序。
优化5:什么情况对快排来讲最坏?原因? 倒序的排号序的数组。因为