qsort函数用法以及如何自己实现

声明

下面是 qsort() 函数的声明。

void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))

参数

  • base -- 指向要排序的数组的第一个元素的指针。
  • nitems -- 由 base 指向的数组中元素的个数。
  • size -- 数组中每个元素的大小,以字节为单位。
  • compar -- 用来比较两个元素的函数。

返回值

该函数不返回任何值。

举例如下:

#include <stdio.h>
#include <stdlib.h>

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

int main()
{
   int values[] = { 88, 56, 100, 2, 25 };
   int sz=sizeof(values)/sizeof(values[0]);
   qsort(values, sz, sizeof(values[0]), cmp);

   printf("\n排序之后的列表:\n");
   for( n = 0 ; n < sz; n++ ) {
      printf("%d ", values[n]);
   }
 
  return(0);
}

 qsort函数就是多功能版的冒泡排序,让我们在冒泡排序的基础上更改;

冒泡排序参数只需要首地址,元素个数,qsort函数的参数分别要传首地址,元素个数,单位字节数,排序规则(是个函数),相同的是有两层循环,外层循环是一共排多少趟,内层是一趟排列多少对,在原地址排序不要要返回值;

if (cmp((char*)base + j*width, (char*)base + (j + 1)*width) > 0)
{
    //交换
	swap((char*)base + j*width, (char*)base + (j + 1)*width, width);
}

 单独解释一下:想要通用排序函数,参数的类型不能单独化,所以地址只能用void*来接收;

但是在比较两数大小时,要解引用,void型不能解引用。在知道单位字节的情况下可以强制转化为(char*)加上整数倍个单位字节数,来访问元素;

当内部循环 j=0 时,第一个元素可以表示为(char*)base+j*width

                                第二个元素可以表示为(char*)base+(j+1)*width

当 前者 大于 后者 时要进行交换,交换函数与冒泡函数有所不同;

最后一点:规则排序函数

排列int型,上面有

再举一个例子,排列结构体类型;

int cmp_stu(const void* e1, const void* e2)
{
	return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name);
    //先强制转化为结构体类型,再解引用;
}
struct stu
{
	char name[20];
	int age;
};
struct stu s[3] = { { "zhangsan", 20 }, { "lisi", 15 }, { "wangwu", 30 } };

当前者大于后者将返回一个正数,与上面判断大于0时交换数据相呼应; 

排列整形源代码如下:

#include <stdio.h>
int cmp_int(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}
void swap(char* buf1, char*buf2, int width)
{
	for (int i = 0; i < width; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}
void my_qsort(void* base, size_t num, size_t width, int(*cmp)(const void*, const void*))
{
	//趟数;
	for (int i = 0; i < num; i++)
	{
		//比较对数;
		for (int j = 0; j < num - 1 - i; j++)
		{
			if (cmp((char*)base + j*width, (char*)base + (j + 1)*width) > 0)
			{
				//交换;
				swap((char*)base + j*width, (char*)base + (j + 1)*width,width);
			}
		}
	}
}
int main()
{
	int arr[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr, sz, sizeof(arr[0]), cmp_int);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

  • 16
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值