回调函数实现冒泡排序及其模拟实现

1.对于一组数实现冒泡排序最普通操作

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    int a[7] = { 0 };
    int tmp = 0;
    while (scanf("%d %d %d %d %d %d %d", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6]) != EOF)
    {
        for (int i = 0; i < 6; i++)/7个数比较6次就行了
        {
            for (int j = 0; j < 6 - i; j++)//第一次比较完后最大值或最小值就放在最后了不需要再参与比较了
            {
                if (a[j] > a[j + 1])
                {
                    tmp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = tmp;
                }

            }
        }
        int sum = 0;
        for (int i = 1; i < 6; i++)
        {
            sum += a[i];
        }
        double average = sum / 5.0;
        printf("%.2lf\n", average);

    }

    return 0;
}

这不是有手就行今天咱换个花样引用个新函数qsort()

2.qsort()

qsort函数C语言编译器函数库自带的排序函数。qsort 的函数原型是void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*)); 是base所指数组进行排序。

我们来分析一下

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

1.void*base是void*型的,base是一个数组名,比如上面我们比较arr[]数组中的数,那base就接受arr[]中的数。

2.num是我们比较的数有几个。

3.size_t width是要比较的值的大小,整数是4字节就这意思。

4.int(__cdecl*compare)(const void*,const void*)是我们自己编一个函数(但是参数要是指针类型)来比较这些数的大小,

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

int int_com(const void* x, const void* y)
{
	//qsort是无类型函数,需要进行强转。
	int* xp = (int*)x;
	int* yp = (int*)y;
	if (*xp > *yp)
	{
		return 1;
	}
	else if (*xp < *yp)
	{
		return -1;
	}
	else {
		return 0;
	}

}

int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int num = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, num, sizeof(int), int_com);
	for (int i = 0; i < num; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

这就是qsort函数的冒泡实现

 3.模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

//模拟实现回调函数实现冒泡排序
int int_cmp(const void* p1, const void* p2)
{
	/*if (*(int*)p1 > *(int*)p2)
		return 1;
	else if (*(int*)p1 = *(int*)p2)
		return 0;
	else
		return 0;
	return (*(int*)p1 - *(int*)p2);*/
	//必须要强制类型转换,要不是void型的的比较不了,字符型强制类型为char*
}
void Swap(char* a1,char* a2,int width)//这里的width的单位是字节如果比较7,8
{/*  07 00 00 00
     08 00 00 00 把他们一个字节一个字节交换
 */
	int i = 0;
	for (i = 0; i < width; i++)
	{
		char tmp = *a1;
		*a1 = *a2;
		*a2 = tmp;
		a1++;
		a2++;
	}
}
void bubble_sort(void* base, int num, int width, int (*cmp)(const void* el, const void* e2))
{
	int i = 0;
	for (i = 0; i < num - 1; i++)
	{
		for (int j = 0; j < num - 1 - i; j++)//跟冒泡排序原理一毛一样
		{
			if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
			{
				/*base强制转换为char*有些难理解,但是width也是字节啊,所以转换*/
				Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
			}
		}
	}
}
void test4()
	{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);//求数组长度
	bubble_sort(arr, sz, sizeof(arr[0]), int_cmp);
	int i = 0;
	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
	}

int main()
{
	test4();
}

这其中最难理解的是就是这个width,其实width=sizeof(arr[0])=4字节(本题中)

再Swap函数中我们是一个字节一个字节来交换的因为一个整数就四字节。

还有这个(char*)base + j * width,这个base代表首元素地址,j=1,我往后跳一个,j=2,我就加8字节,往后跳两个,就这意思。

行了,图书馆撵人了,再见!

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值