【C语言】快速排序函数qsort()

函数原型

#include<stdlib.h>

void qsort(void*, size_t, size_t, int ( * )(const void * ,  const void *  ))
  1. 第一个参数为待排序数组首地址。

可直接输入待排序数组名,或是指向数组的指针。

  1. 第二个参数为数组长度。

size_t是标准C库中定义的,应为unsigned int,在64位系统中为 long unsigned int。
可以直接输入待排序的数组的长度。

  1. 第三个参数为数组元素所占字节。

可直接用sizeof(a[0])计算字数组单个元素的节数。

  1. 第四个参数为所调用函数的指针,函数名即是函数的指针,可直接写函数名,调用函数用来确定排序的方式。

先以整型递增排序为例

int inc (const void * a,const void *b)
 {
return * (int * )a-* (int *)b;
}
  1. int inc 表示函数返回一个int值。inc为函数名 ,表示递增排序(increase),也可以自己命名。
  2. ( const void * a, const void * b)将两个要对比的元素的地址传入函数。 (加const表示无法改变指针指向的值)
  3. return * ( int * )a - * ( int * ) b ,返回一个整型数,表示两个元素对比的结果。如果a大于b,则返回正数。a小于b,则返回负数。如果a等于b,则返回零。(int *)表示将地址强制类型转换成整形地址类型,可根据排序对象选择指针类型的转换。也可以改变算式,例如用 return strlen((char * )a) > strlen((char * )b) ? 1 : -1; 可以返回比较字符串长度的结果,用来根据字符串长度进行排序, 下面有相关的代码。

各种数据类型的升序排序函数

(如果要降序排序,只需将return里的a,b反过来写即可。)

1. 整型

int inc (const void * a,const void *b)
 {
return *(int *)a - *(int *)b;
}

2. double型

int inc (const void * a, const void * b)
{
return *(double *)a > *(double *)b ? 1 : -1;
}

注: 这里两个浮点数相减但要返回一个整型数,如果按上面做法直接减会丢失小数点部分。所以需另加处理,直接判断大小,如果a大于b,则返回1,否则返回-1。

3. 字符排序

int inc(const void *a,const void *b)
{
   return *(char *)a - *(char *)b;
}

4. 字符串排序

char am = { {"...."}, {"....."}, .....};
qsort(a, m, sizeof(char * )  * n, inc);
1. 根据字符串首字母排序
  ```c
  int inc(const void *a, const void *b)  
  {  
  return * (char *)a - *(char * )b;  
  }  
  ```
2. 根据字符串长度排序
  ```c
  int inc(const void *a, const void *b)  
  {  
  return strlen((char * )a) > strlen((char * )b) ? 1 : -1;  
  } 
  ```

注:这里不要用 return strlen((char * )a) - strlen((char * )b) ;
原因:
1. strlen返回类型为size_t,size_t是标准C库中定义的,应为unsigned int,在64位系统中为 long unsigned int。无符号整型最好不要做四则运算。
2. 这里虽然函数返回int型,会把无符号数转换为整型,但返回结果只在字符串的长度未超过int的范围时正确。这种大范围转小范围要考虑精度损失的问题。

3. 按字典排序字符串。
  ```c
  int inc(const void *a, const void *b)
  {
   return (strcmp((char *)a, (char *)b));
  }
  ```

5. 结构体

struct node
{
   double one;
   int two;
} s[100];
1.一级排序

根据double型的one的大小排序结构体。

int inc( const void *a ,const void *b)
{
return ( * (node * )a).one > ( * (node * )b).one ? 1 : -1;
}

2.二级排序

先根据double型的one的大小排序,若两值相等,在根据int型two的大小排序。

int inc( const void *a , const void *b )
{
if((* (node * )a).one != ( * (node * )b).one)
return ( * (node * )a).one > ( * (node * )b).one ? 1 : -1;
else return (* (node * )a).two -( * (node * )b).two;
}

具体样例

1. 整型

#include<stdio.h>
#include<stdlib.h>
#define L 20
int inc(const void *a, const void *b)
{
	return *(int *)a - *(int *)b;
 } 
int main ()
{
	int a[L] = {0, 5, 2, 3, 4, 9, 8, 7, 6, 1,
		11, 15, 14, 12, 13, 16, 17, 18, 19, 10};
	qsort(a, L, sizeof(int), inc);
	for (int i = 0; i < L; i++)
	{
		printf("%d ", a[i]);
	}
 } 

整型结果

2.double型

#include<stdio.h>
#include<stdlib.h>
#define L 20
int inc(const void *a, const void *b)
{
	return *(double *)a > *(double *)b? 1 : -1;
 } 
int main ()
{
	double a[L] = {0.1, 0.11, 1.1, 1.5, 1.8, 1.51, 2.5, 2.9, 1.3, 0.8, 
		15.5, 7.9, 8.5, 8.51, 8.6, 3, 1.41, 1.11, 1.51, 2};
	qsort(a, L, sizeof(double), inc);
	for (int i = 0; i < L; i++)
	{
		printf("%.2lf\n", a[i]);
	}
 } 

运行结果 :
double

3.字符型

#include<stdio.h>
#include<stdlib.h>
#define L 20
int inc(const void *a, const void *b)
{
	return *(char *)a - *(char *)b;
 } 
int main ()
{
	char a[L] = {'q', 'w', 'r', 'h', 'a', 'v', 'g', 'e', 'b', 'l',
		'o', 'p', 'u', 'y', 't', 'c', 'x', 'i', 'z', 's'};
	qsort(a, L, sizeof(char), inc);
	for (int i = 0; i < L; i++)
	{
		printf("%c ", a[i]);
	}
 } 

运行结果 :
这里写图片描述

4.字符串

  1. 按首字母排序
#include<stdio.h>
#include<stdlib.h>
#define L 10
#define K 10
int inc(const void *a, const void *b)
{
	return *(char *)a - *(char *)b;
 } 
int main ()
{
	char a[L][K] = {
		"rbsc",
		"jcse",
		"efgd",
		"arbs",
		"bbs",
		"cbfe",
		"dgafg" ,
		"ewqrta",
		"ofgd",
		"mbcv",
	};
	qsort(a, L, sizeof(char) * K, inc);
	for (int i = 0; i < L; i++)
	{
		printf("%s\n", a[i]);
	}
 } 

运行结果 :
这里写图片描述

  1. 按长度排序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define L 10
#define K 10
int inc(const void *a, const void *b)
{
	return strlen((char *)a) > strlen((char *)b) ? 1 : -1;
 } 
int main ()
{
	char a[L][K] = {
		"rbsc",
		"jcsse",
		"efgdsd",
		"arbs",
		"bbs",
		"cbfefaa",
		"dgafg" ,
		"ewqrta",
		"ofgd",
		"mbcv312",
	};
	qsort(a, L, sizeof(char) * K, inc);
	for (int i = 0; i < L; i++)
	{
		printf("%s\n", a[i]);
	}
 } 

运行结果 :
这里写图片描述
3. 按字典顺序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define L 10
#define K 10
int inc(const void *a, const void *b)
{
	return strcmp((char * )a, (char *)b);
 } 
int main ()
{
	char a[L][K] = {
		"rbsc",
		"jcsse",
		"afgdsd",
		"arbs",
		"abs",
		"cbfefaa",
		"cgafg" ,
		"ewqrta",
		"ofgd",
		"mbcv312",
	};
	qsort(a, L, sizeof(char) * K, inc);
	for (int i = 0; i < L; i++)
	{
		printf("%s\n", a[i]);
	}
 } 

运行结果:
这里写图片描述

5.结构体

结构体二级排序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define L 10
typedef struct node {
 	double first;
 	int numb;
 }node;
 
int inc(const void *a, const void *b)
{
	if((* (node *)a).first != ( * (node *)b).first)
	return ( * (node * )a).first > ( * (node * )b).first ? 1 : -1;
	else return (* (node * )a).numb -( * (node * )b).numb;

 } 
 
int main ()
{
	node arr[L] = {
		1.0, 1,
		2.0, 2,
		1.1, 3,
		2.1, 4,
		3.5, 5,
		1.0, 6,
		1.1, 7,
		5.1, 8,
		5.0, 9,
		3.6, 10,
		
	};
	qsort(arr, L, sizeof(node), inc);
	for (int i = 0; i < L; i++)
	{
		printf("%.2lf %d\n", arr[i].first, arr[i].numb);
	}
 } 

运行结果:
这里写图片描述

评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值