qsort用于结构体数组排序

用模拟的qsort进行解释结构体数组的排序

typedef struct Stu{
	char name[100];
	char sex[10];
}stu;

void Swap(void *_x, void *_y,int size)
{
	char *x = (char *)_x;
	char *y = (char *)_y;
	char temp = 0;
	while (size)//每次指针移动一个字节,将size(元素的带下)个字节全部交换
	{
		temp = *x;
		*x = *y;
		*y = temp;
		x++;
		y++;
		size--;
	}
}
int com(const stu *x,const stu *y)//传进来的是数组的地
{
	return (strcmp(x->sex,y->sex));
}
void My_qsort(void *base, int num, int size, int const(*com)(const void*, const void *))
{
	assert(base);
	assert(com);
	char *e = (char *)base;//接收的是void*,不管什么类型都强转为char*,每次指针移动1个字节
	for (int i = 0; i < num - 1; i++)//冒泡排序
	{
		int flag = 0;
		for (int j = 0; j < num - 1 - i; j++)
		{
			if (com(e + j*size, e + (j + 1)*size)>0)//前者大于后者进行交换
			{
				Swap(e + j*size, e + (j + 1)*size,size);
			}
			flag = 1;
		}
		if (!flag)
			break;
	}

}

int main()
{//这里是伪代码
	stu p[3];
	My_qsort(p, 3, (int)sizeof(p[0]), com);
	system("pause");
	return 0;

qsort第一个传入的参数为需要排序的元素的首地址,很明显我们能看到传了结构体数组的数组名即首元素地址;
然后传了一个3,代表数组有多少个元素需要进行排序,这个数字在冒泡排序中控制循环排序的次数;
再传入一个结构体数组的大小,这个大小在排序函数中起到的作用是控制指针每次移动的距离以及进行交换时需要交换多少个字节的内容。
可以看到排序函数接收的void*,然后被强转成char*,因此每次指针移动只能移动一个字节,传入size后,每次移动size个字节即到了下一个元素;
在交换函数Swap中,每次也是只进行一个字节内容的交换,通过size知道需要交换多少个字节的内容,因此交换完size字节即完成两个元素的交换;

需要特别注意的是每次传入的参数起点必须是数组中的元素地址或者对应的结构体第一个元素地址,不能是结构体中第一个元素之外的地址。因为这个是作为起点的,size决定了移动的距离和交换的大小,如果改变起点就造成数据的混乱,排序出来后数组中的内容就交错混乱了;

猜你喜欢

转载自blog.csdn.net/ych9527/article/details/111415759