C语言qsort()库函数

part 1.认识qsort()函数

qsort()库函数原型如下:

/*void* base----指向待排序数据的起始位置的一个指针
size_t size---- 由base指向的数组中元素的个数。
size_t width----数组中每个元素的大小,以字节为单位	
int(__cdecl *compare )(const void *elem1, const void *elem2 )----用来比较两个元素的函数,即函数指针(函数回调)
*/
void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

如果想要升序(降序)代码示例如下:
此函数是专门比较(int)的,如需比较其他型,请把此处的(int*)更改。

int cmp_int(const void* e1, const void* e2)
{
    
    
	//升序
	//return (*(int *)e1 - *(int*)e2); 

	//降序
	return (*(int*)e2 - *(int*)e1);
}

在这里插入图片描述

part 2.简单运用qsort()函数

下面我们先运用qsort()函数排序一个一维数组。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//打印数组函数
//int* arr---整形指针指向数组
//int sz --存储数组的大小
void print(int* arr, int sz)
{
    
    
	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
    	
		printf("%d ", arr[i]);
	}
}
/*如果compar返回值小于0(< 0),那么e1所指向元素会被排在e2所指向元素的左面;
如果compar返回值等于0(= 0),那么e1所指向元素与e2所指向元素的顺序不确定;
如果compar返回值大于0(> 0),那么e1所指向元素会被排在e2所指向元素的右面。*/
int cmp_int(const void* e1, const void* e2)
{
    
    
	//升序
	//return (*(int *)e1 - *(int*)e2); 

	//降序
	return (*(int*)e2 - *(int*)e1);
}
void test1()
{
    
    
	//运用qsort 排序一个整形数组
	int arr[] = {
    
     9,0,5,7,6,1,3,2,8 ,4 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//需要引头文件---- #include<stdlib.h>
	qsort(arr, sz, sizeof(arr[0]), cmp_int);
	print(arr, sz);
}
int main()
{
    
    	
	test1();
	return 0;
}

既然能排序数组,那能不能排序结构体呢?
答案是:能。具体示例如下代码:

struct stu
{
    
    
	char m_name[20];   //姓名
	int  age;          //年龄
};
/*如果compar返回值小于0(< 0),那么e1所指向元素会被排在e2所指向元素的左面;
如果compar返回值等于0(= 0),那么e1所指向元素与e2所指向元素的顺序不确定;
如果compar返回值大于0(> 0),那么e1所指向元素会被排在e2所指向元素的右面。*/
int cmp_age(const void* e1, const void* e2)
{
    
    
	//按年龄升序
	return (*(stu*)e1).age - (*(stu*)e2).age;

	//按年龄降序
	//return (*(stu*)e2).age - (*(stu*)e1).age;
}
int cmp_name(const void* e1, const void* e2)
{
    
    
	//按名字升序
	//当然字符串不能像之前那样直接比较
	//而应该使用库函数strcmp()来比较大小
	/*strcmp()函数原型
	int strcmp( const char *string1, const char *string2 );
	当s1<s2时,返回为负数;
	当s1=s2时,返回值= 0;
	当s1>s2时,返回正数
	*/
	return strcmp((*(stu*)e1).m_name,(*(stu*)e2).m_name);

	//按名字降序	
	//return strcmp((*(stu*)e2).m_name,(*(stu*)e1).m_name);
}

void test2()
{
    
    
	//使用qsort函数排序结构体
	stu arr[] = {
    
     {
    
    "zhansan",20},{
    
    "lisi",30},{
    
    "wangwu",10} };
	int sz=sizeof(arr) / sizeof(arr[0]);
	//按年龄排序
	qsort(arr, sz, sizeof(arr[0]), cmp_age);  //-----qsort的第四个参数是函数指针

	//按名字排序
	qsort(arr, sz, sizeof(arr[0]), cmp_name);
}
int main()
{
    
    	
	test2();
	return 0;
}

part 3.用冒泡排序模拟实现库函数qsort()

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void _swap(char* buf1, char* buf2,size_t width)
{
    
    
	int i = 0;
	for (i = 0; i < width; i++)
	{
    
    
		//一个字节一个字节的交换
		char temp = *buf1;
		*buf1 = *buf2;
		*buf2 = temp;
		buf1++;
		buf2++;
	}
}
void bubble_sort(void* base, size_t size, size_t width, int (*cmp)(const void* e1, const void* e2))
{
    
    
	size_t i = 0;
	for (i = 0; i < size - 1; i++)
	{
    
    
		size_t j = 0;
		//判断是否排好序的一个标志
		/*如果flag==true则证明这趟还没排好序,如果flag==false,则排好序,之后的趟数可以
		不用进行了*/
		bool flag = false;   
		for (j = 0; j < size - 1 - i; j++)
		{
    
    
			//相邻俩个元素的比较
			//(char*)的强制类型转换为了实现一个字节一个字节的加减,方便找到之后元素
			//+j*width可以找到第j号元素的首地址,依次类推
			//就像冒泡排序一样if(arr[j]>arr[j+1])就交换
			if (cmp((char *)base+j*width,(char *)base+(j+1)*width)>0)
			{
    
    
				//如果不满足顺序就交换
				_swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
				flag = true;
			}
		}
		if (false == flag)
		{
    
    
			break;
		}
	}
}

struct stu
{
    
    
	char m_name[20];  //名字

	int  age;         //年龄
};

int cmp_age(const void* e1, const void* e2)
{
    
    
	//按年龄升序
	return (*(stu*)e1).age - (*(stu*)e2).age;

	//按年龄降序
	//return (*(stu*)e2).age - (*(stu*)e1).age;
}

int cmp_name(const void* e1, const void* e2)
{
    
    
	//按名字升序
	return strcmp((*(stu*)e1).m_name, (*(stu*)e2).m_name);

	//按名字降序	
	//return strcmp((*(stu*)e2).m_name,(*(stu*)e1).m_name);
}

void test3()
{
    
    
	stu arr[] = {
    
     {
    
    "zhansan",10},{
    
    "lisi",20},{
    
    "wangwu",30} };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//按年龄排序
	bubble_sort(arr, sz, sizeof(arr[0]), cmp_age);
	//按名字排序
	//bubble_sort(arr, sz, sizeof(arr[0]), cmp_name);

}

int main()
{
    
    
	test3();
}

猜你喜欢

转载自blog.csdn.net/weixin_47812603/article/details/113575612