顾名思义,快速排序对于绝大多数数组排序有较高的效率,快速排序适用于数据量比较大的数组进行排序,但对于有些譬如基本顺序结构进行排序时效率较低,对于有些小于25个元素的数组排序时效率甚至不如插入排序。
对于快速排序,有两种常见的版本:1.传统法--horare版本 2.挖坑法。
两种方法思想上大同小异,其中挖坑法效率略高。
代码思想(先以horare版本为例):
1.数组的首元素角标记为low,最后一个元素角标记为high,不妨取首元素为关键位置key,对该元素找到合适的位置即可。
2.为关键字key找位置插入(即在这个数组中排好元素6),假设已经排好的理想位置为:key的左边都比6小,而右边都比6大,我们就排好了6这个元素。
具体方法:
先从最右边看,如果比6大则可以忽略,即可以让high--;如果比6小,则交换。
再从最左边看,如果比6小则可以忽略,即可以让low++;如果比6大,则交换。
然后往复循环,我们就给6找到合适的位置!
3.可以已经排好的元素6的左端和右端排序排好每个元素的位置,即可为整个数组完成排序:
显然,这需要对左数组和右数组进行递归即可。
而挖坑法和horare版本的区别在于,不使用交换,而是将low的值保存下来,把low的位置空闲出来,方便把high的值赋进去,此时,high的位置空闲了,又方便把low的值赋进去了,直到low=high时,再把key赋进去。
程序代码:
void QuickSort(int arr[], int low, int high)
{
if (low >= high)
return;
int key = partition(arr, low, high);//找位置,每次只能排一个位置,其余数组位置排位则需要递归
QuickSort(arr, low, key-1);
QuickSort(arr, key + 1, high);
}
//1.传统法--horare版本
int partition(int* arr, int low, int high)
{
int key = arr[low];//此题中,key会在low和high直接反复横跳
while (low < high)//大循环内先右后左,每次仅进行一次交换
{
while (low < high && arr[high] >= key)//满足要求则向左靠,注意:在下面high--的过程中,可能会在内循环中出现low>high的情况,违背外循环的条件,出现崩溃,所以要加先决条件:low<=high
high--;
swap(arr, low,high);//当跳出上述循环时,说明不符合while的条件,此时需要交换
while (low < high && arr[low] <= key)
low++;
swap(arr,low,high);
}
return low;
}
//2.挖坑法
//int partition(int* arr, int low, int high)//本质上依然是交换low,high,比传统法效率更高
//{
// int key = arr[low];//此题中,key的位置会空出来,low为初始坑位
// while (low < high)//大循环内先右后左
// {
// while (low < high && arr[high] >= key)//满足要求则向左靠,注意:在下面high--的过程中,可能会在内循环中出现low>high的情况,违背外循环的条件,出现崩溃,所以要加先决条件:low<=high
// high--;
// arr[low]=arr[high];
//
// while (low < high && arr[low] <= key)
// low++;
// arr[high]=arr[low];
// }
// arr[low] = key;//找到后再在key的位置进行赋值
// return low;
//}
void swap(int* arr, int low, int high)
{
int tmp = arr[low];
arr[low] = arr[high];
arr[high] = tmp;
}
void PrintArray(int arr[], int left, int right)
{
for (int i = left; i < right; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
void main()
{
int arr[] = { 49,38,65,97,76,13,27,49 };
int n = sizeof(arr) / sizeof(arr[0]);
QuickSort(arr, 0, n-1);
PrintArray(arr, 0, n);
}