冒泡排序进阶

本次在学习c语言的时候,学到冒泡排序,但是这只能对整型的数据类型排序,没有办法对字符型或者结构型数据类型进行排序,因此这里扩展一个通用的冒泡排序法

 这里先看原来冒泡排序的方法,不做过多介绍,可以先复习一下

void bubble_sort(int arr[], int sz)
{
	int i = 0;
	//趟数
	for (i = 0; i < sz-1; i++)
	{
		int flag = 1;//假设数组是排好序的
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = 0;
			}
		}
		if (flag == 1)//如果已经是排好序的,那么flag等于1,无须再进行后面的排序
		{
			break;
		}
	}
}
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0};
	//数组排成升序
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d", arr[i]);
	}
	return 0;
}

接着我们要学习一个新的函数-------qsort函数


qsort函数

msdn解释如下:

void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

qsort使用的是快速排序思想实现的排序函数,是c语言本身提供的函数,参数__cdecl *compare是函数调用约定,这里不做多介绍,const void* e1,const void*e2是函数指针,void* base是排序的起始位置,num是待排序的数据元素的个数,width是待排序的数据元素的大小,单位为字节。

这个函数可以排序任意类型的数据类型,我们回来看最初冒泡排序的算法,我们知道现在这个冒泡排序不完美在于他只能排序整型类型,因此我们需要改变的是参数的类型,还有两个元素间的比较,但是这里也有一个问题------不同的数据类型排序方法不同

所以qsort函数将不同类型数比较方法提取出来,就是参数中int (*cmp)(const void *elem1, const void *elem2 ) )这个函数指针,这个比较方法由我们定义,相当于回调函数

qsort返回值:

  • Return ValueDescription
    < 0elem1 less than elem2
    0elem1 equivalent to elem2
    > 0elem1 greater than elem2

 


qsort函数排序整型

因此我们可以写出代码(这里以整型类型比较为例):

cmp_int(const void* e1, const void* e2)
{
	if (*e1 > *e2)
		return 0;
	else if (*e1 == *e2)
		return 0;
	else
		return -1;
}

这里返回0,1,-1好让qsort知道我们比较整型的大小结果

好像明白了,但是还是有个问题,就是我们设立函数去比较时候,肯定调用void*的函数(void*是无具体类型的指针,可以接收任意类型的地址,所以不能解引用,也不能+-整数)但是我们没办法将void*指针解引用呀,所以我们要将void*强制类型转换

修改如下:

cmp_int(const void* e1, const void* e2)
{
	if (*(int*)e1 > *(int*)e2)
		return 0;
	else if (*(int*)e1 == *(int*)e2)
		return 0;
	else
		return -1;
}

但是这样语句比较啰嗦,我们可以用相减的方法去判断结果正负:

//比较两个整型元素
//e1指向一个整数
//e2指向另一个整型
int cmp_int(const void* e1, const void* e2)
{
	return (*(int*)e1 - *(int*)e2);
}

int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0};
	//数组排成升序
	int sz = sizeof(arr) / sizeof(arr[0]);
	/*bubble_sort(arr, sz);*/
	qsort(arr, sz, sizeof(arr[0]), cmp_int);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d", arr[i]);
	}
	return 0;
}

如果要想改变为降序,只需要改为return (*(int*)e2 - *(int*)e1);就可以了


qsort排序结构体类型

直接上代码,详细解释注释已标:

struct Stu
{
	char name[20];
	int age;
};

int cmp_stu_by_name(const void* e1,const void* e2)
{
	//strcmp返回的值恰好为>0,<0,=0
	//这里比较名字,为字符串,因此需要strcmp函数来比较,strcut Stu*为强制类型转换
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}

//测试使用qsort来排序结构数据
void test1()
{
	struct Stu s[] = { {"zhangsan",15},{"lisi",30},{"wangwu",25} };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}

注意:strcmp比较是一个字符一个字符的比较,比如a>b,b>c

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值