qsort函数的使用及其通过冒泡排序实现

目录

1.qsort函数的使用

1.1 qsort函数参数介绍

1.2qsort函数的使用

2.qsort函数通过冒泡排序实现


1.qsort函数的使用

1.1 qsort函数参数介绍

void qsort( void *base,//你要排序的数据的起始位置

size_t num,//待排序的数据元素的个数

size_t width, //待排序的数据元素的大小(单位是字节)

int (__cdecl *compare )(const void *elem1, const void *elem2 ) );//函数指针-比较函数

1.2qsort函数的使用

头文件的调用:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

qsort排序的各种类型:

//int类型的比较
int cmp1(const void* p1, const void* p2)
{

	return *(int*)p1 - *(int *)p2;
}


void test1()
{
	int arr1[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
	int i = 0;

	qsort(arr1, 10, sizeof(int), cmp1);

	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	printf("\n");
}
//char类型的比较

int cmp2(const void* p1, const void* p2)
{
	return *(char*)p1 - *(char *)p2;
}

void test2()
{
	char arr2[5] = { 'N', 'E', 'A', 'V', 'B' };
	int i = 0;

	qsort(arr2, 5, sizeof(char), cmp2);

	for (i = 0; i < 5; i++)
	{
		printf("%c ", arr2[i]);
	}
	printf("\n");
}
//浮点类型的比较
int cmp3(const void* p1, const void* p2)
{

	return (int)(*(float*)p1 - *(float *)p2);
}

void test3()
{
	float arr3[] = { 1.0f, 0.9f, 2.1f, 3.1f, 5.1f };
	
	int i = 0;

	qsort(arr3, sizeof(arr3) / sizeof(arr3[1]), sizeof(float), cmp3);

	for (i = 0; i < 5; i++)
	{
		printf("%f ", arr3[i]);
	}
	printf("\n");
}
//结构体类型的比较
typedef struct student
{
	char name[20];
	int  age;
}stu;

int cmp4(const void* p1, const void* p2)
{
	return strcmp(((stu*)p1)->name, ((stu*)p2)->name);
}

int cmp5(const void* p1, const void* p2)
{
	return ((struct student*)p1)->age - ((struct student*)p2)->age;
}

void test4()
{
    stu arr4[3] = { "zhangsan", 14, "lisi", 12, "angwu", 11 };

	int i = 0;

	qsort(arr4, 3, sizeof(stu), cmp4);

	qsort(arr4, 3, sizeof(stu), cmp5);


	for (i = 0; i < 3; i++)
	{
		printf("%d ", arr4[i].age);
		printf("%s ", arr4[i].name);
	}
	printf("\n");

}

主函数:

int main()
{
	test1();
	test2();
	test3();
	test4();


	return 0;
}

2.qsort函数通过冒泡排序实现

void swap(char* buf1,char* buf2,int width)
{
	int i;

	for (i = 0; i < width; i++)
	{
		char temp = *buf1;
		*buf1 = *buf2;
		*buf2 = temp;
		buf1++;
		buf2++;
	}
}

void bubble_qsort(void *base, size_t num, size_t width, int(*cmp)(const void*p1, const void*p2))
{
	int i, j;
	for (i = 0; i< num; i++)
	{
		int flag = 1;
		for (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);
//这里表示前面一个元素与后面一个元素相差一个类型,width就是字节的大小 首地址+字节的大小=元素类型
//j*width是为了确定前后元素地址的变化	
		}
			flag = 0;
		}
		if (flag == 1)
		{
			break;
		}
	}
	
}

int cmp(const void*p1, const void* p2)
{
	return *(int*)p1 - *(int*)p2;
}

int main()
{
	int arr[5] = { 8, 2, 0, 5, 7 };

	bubble_qsort(arr, 5, sizeof(arr[0]), cmp);

	int i;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

总结:1.qsort函数通过冒泡排序实现,首先应该知道用void的指针来接受任意类型的数组的首元素地址,然后将其转化为char类型的指针,由于char*的指针进行解引用一次访问一个字节,那么就能实现通过char*指针对数字一个字节一个字节的替换。例如冒泡就是每次交换的是4字节,我们的思想是将四字节变小成一字节来处理,就是将不同类型强制转换为char*指针来接受然后进行处理。

2.这里需要函数调用(因为不同人会用不同的类型,所以我们需要他自己确定好类型,让他自己写个比较函数),然后就是理解参数的运用。

-------如有不妥之处还请指正

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
冒泡排序和快速排序qsort)虽然都是常见的排序算法,但它们的工作原理和效率有很大的不同。冒泡排序是一种简单的比较排序算法,而快速排序则是一种高效的分治策略。如果你想了解如何模仿`qsort`实现冒泡排序,其实这不是一个直接的对应,因为`qsort`是基于分治法的高效排序,而冒泡排序更适合教学和理解基本排序原理。 不过,为了满足你的要求,我们可以探讨一下如何用类似`qsort`的方式设计一个冒泡排序的“迭代”版本,虽然这并不是真正意义上的模仿,因为它们在实现上并不相同。 **冒泡排序的简化版(不是真正的`qsort`)**: 1. 定义一个辅助函数,类似于`qsort`的分区过程,但仅用于比较相邻元素并交换: ```c++ void bubbleSortPartition(int arr[], int low, int high) { while (low < high) { if (arr[low] > arr[high]) { std::swap(arr[low], arr[high]); } low++; high--; } } ``` 2. 用递归调用的方式实现冒泡排序: ```c++ void bubbleSortIterative(int arr[], int size) { for (int i = 0; i < size - 1; i++) { bubbleSortPartition(arr, 0, size - 1 - i); } } ``` 这里我们不是直接将整个数组作为一次排序,而是每次缩小待排序范围,直到整个序列有序。 **相关问题--:** 1. 冒泡排序与快速排序的主要区别是什么? 2. 在冒泡排序中,为什么要使用`bubbleSortPartition`函数? 3. 如何评价这种将冒泡排序与`qsort`风格结合的简化版本?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

includeevey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值