1.快速排序
一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用。
1.1快速排序思想与图解
双向排序
- 先从数列中取出一个数作为基准数。
- 分区过程,将比这个数小的或等于的数全放到它的左边,大于它的数全放到它的右边。
- 再对左右区间重复第二步,直到各区间只有一个数。
单向排序
-
定义i,j两个快慢指针,取出i位置数作为基数,
-
如果j<基数,i++并交换i和j,
-
让j++,如果j>基数,j++,如果再有j<基数,让i++,并交换i和j,直到j到最后一个。
-
最后交换i和基数值位置
1.2代码实现
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
快速排序:适合于越没有序的数组
//交换函数
void Swap_Int(int* ap, int* bp)
{
assert(ap != nullptr && bp != nullptr);
int tmp = *ap;
*ap = *bp;
*bp = tmp;
}
//划分函数 双向
int Parition(int* br, int left, int right)
{
assert(br != nullptr);
int i = left, j = right;
int tmp = br[i];
while (i < j)
{
while (i< j && br[j] > tmp) --j;
if (i<j) br[i] = br[j];
while (i<j && br[i] <= tmp) ++i;
if (i<j) br[j] = br[i];
}
br[i] = tmp;
return i;
}
//单向
//int OWParition(int* br, int left, int right)
//{
// assert(br != nullptr);
// int i = left;
// int j = i + 1;
// int tmp = br[i];
// while (j <= right)
// {
// if (br[j] <= tmp)
// {
// i = i + 1;
// Swap_Int(&br[i], &br[j]);
// }
// ++j;
// }
// Swap_Int(&br[left], &br[i]);
// return i;
//}
void QuickPass(int* br, int left, int right)
{
if (left < right)
{
int pos = Parition(br, left, right);//双向快排
//int pos = OWParition(br,left,right)//单向快排
QuickPass(br, left, pos - 1);//左区域
QuickPass(br, pos + 1, right);//右区域
}
}
//快速排序函数
void QuickSort(int* br, int n)
{
assert(br != nullptr);
QuickPass(br, 0, n - 1);//0 - n-1 整个区域规模
}
//打印函数
void Print_Ar(int* br, int n)
{
assert(br != nullptr);
for (int i = 0; i < n; ++i)
{
printf("%5d", br[i]);
}
printf("\n");
}
int main()
{
int ar[] = { 56, 78, 12, 34, 90, 67, 23, 89, 100, 45 };
int n = sizeof(ar) / sizeof(ar[0]);//n是元素个数
QuickSort(ar, n);
Print_Ar(ar, n);
return 0;
}
1.3结果展示
2.快速排序的调用
2.1快排函数:
typedef int (* ComFun)(void const*, void const*);
void qsort(void* _Base,size_t _Num, size_t _Size, ComFun _comfun) ;
2.2代码举例1(int):
//打印函数
void Print_Ar(int* br, int n)
{
assert(br != nullptr);
for (int i = 0; i < n; ++i)
{
printf("%5d", br[i]);
}
printf("\n");
}
//int比较函数
int compare_ints(const void* ap, const void* bp)
{
assert(ap != nullptr && bp != nullptr);
int arg1 = *(const int*)ap;
int arg2 = *(const int*)bp;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
//return arg1 - arg2;// INT_MIN; error;
//return (arg1 > arg2) - (arg1 < arg2); // ok;
}
int main()
{
int ar[] = { 56, 78, 12, 34, 90, 67, 23, 89, 100, 45 };
int n = sizeof(ar) / sizeof(ar[0]);
qsort(ar, n, sizeof(int), compare_ints);//调用快排函数
Print_Ar(ar, n);
return 0;
}
2.3代码举例2(double):
void Print_double(const void* ap)
{
const double* dp = (const double*)ap;
printf("%f ", *dp);
}
//泛型打印函数
void Print_Ar(void* br, int n, int size, void (*Print)(const void*))
{
const char* p = (const char*)br;
for (int i = 0; i < n; ++i)
{
Print(p);
p = p + size;
}
}
//double比较函数
int compare_doubles(const void* ap, const void* bp)
{
assert(ap != nullptr && bp != nullptr);
double arg1 = *(const double*)ap;
double arg2 = *(const double*)bp;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
}
int main()
{
double ar[] = { 5.6,7.8,1.2,3.4,9.0,6.7,2.3,8.9,10.0,4.5 };
int n = sizeof(ar) / sizeof(ar[0]);
qsort(ar, n, sizeof(double), compare_doubles);
Print_Ar(ar, n,sizeof(double),Print_double);
return 0;
}
今天也要好好学习呀~