C语言--快速排序

1.快速排序

一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用。

1.1快速排序思想与图解

双向排序

  1. 先从数列中取出一个数作为基准数。
    在这里插入图片描述
  2. 分区过程,将比这个数小的或等于的数全放到它的左边,大于它的数全放到它的右边。
    在这里插入图片描述
  3. 再对左右区间重复第二步,直到各区间只有一个数。

单向排序

  1. 定义i,j两个快慢指针,取出i位置数作为基数,
    在这里插入图片描述

  2. 如果j<基数,i++并交换i和j,

  3. 让j++,如果j>基数,j++,如果再有j<基数,让i++,并交换i和j,直到j到最后一个。

  4. 最后交换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;
}

今天也要好好学习呀~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鹿可可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值