学会快速排序库函数qsort的使用以及实现

  • qsort的使用
    • 使用细节一
    • 完成代码
  • qsort的实现(用冒泡排序)
    • 写法一
    • 写法二
    • 完整代码

qsort的使用

qsort函数的官方介绍: 点这里
学会快速排序库函数qsort的使用以及实现_第1张图片
qsort函数需要包含头文件
qsort函数有四个参数,逐一介绍
base:指向数组中要排序的第一个对象的指针,转换为void*
num:基数指向的数组中元素的个数。Size_t是一个无符号整型
size:数组中每个元素的字节大小。Size_t是一个无符号整型
compar:指向比较两个元素的函数的指针

这个函数被qsort反复调用以比较两个元素。这个函数的格式为
int compar (const void* p1, const void* p2);

这个函数需要做到为qsort提供参数。

返回值 含义
小于0的值 p1所指向的元素比p2所指向的元素“小”,需要排在p2前面
0 p1所指向的元素和p2所指向的元素一样大
大于0的值 p1所指向的元素比p2所指向的元素“大”,需要排在p2前面
补充说明 在vs中这三个值一般是1、0、-1

使用细节一

浮点数无法直接比较大小,这里的实现方法需要牢牢掌握
先需要宏定义一个EPS,值为1e-7,这是哥非常非常小的值(1×10^-7),当俩浮点数之差的绝对值小于EPS时,可以代表这俩浮点数相等。

#include
#include
#include//fabs//绝对值

#define EPS 1e-7 //判断浮点数是否位于0的一个很小的邻域内[-EPS,EPS]内

typedef struct STU
{
	char name[10];
	int age;
	float TotalScore;
}Stu;

int CmpFloat(const void* p1, const void* p2)
{
	if (fabs((*(float*)p1 - (*(float*)p2)) <= EPS))
	{
		return 0;
	}
	else if ((*(float*)p1 - (*(float*)p2) > EPS))
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

void TestFloat()
{
	float arr[] = { 1.2f,3.4f,2.8f,8.4f,6.3f };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), CmpFloat);
}

int main()
{
	TestFloat();
	return 0;
}

完成代码

#define _CRT_SECURE_NO_WARNINGS 1

//库函数qsort的使用
//void qsort (void* base, 
			// size_t num, 
			// size_t size,
			// int (*compar)(const void*, const void*));
//char int float struct

#include
#include//qsort
#include//fabs//绝对值

#define EPS 1e-7 //判断浮点数是否位于0的一个很小的邻域内[-EPS,EPS]内

typedef struct STU
{
	char name[10];
	int age;
	float TotalScore;
}Stu;

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

void TestInt()
{
	int arr[] = { 7,5,9,1,3,2,4,6,8,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), CmpInt);
}

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

void TestChar()
{
	char arr[] = "AKRZXIY";
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), CmpChar);
}

int CmpFloat(const void* p1, const void* p2)
{
	if (fabs((*(float*)p1 - (*(float*)p2)) <= EPS))
	{
		return 0;
	}
	else if ((*(float*)p1 - (*(float*)p2) > EPS))
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

void TestFloat()
{
	float arr[] = { 1.2f,3.4f,2.8f,8.4f,6.3f };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), CmpFloat);
}

int CmpStructName(const void* p1, const void* p2)
{
	return strcmp((*(Stu*)p1).name,(*(Stu*)p2).name);
}

int CmpStructAge(const void* p1, const void* p2)
{
	return ((*(Stu*)p1).age - (*(Stu*)p2).age);
}

int CmpStructTotal(const void* p1, const void* p2)
{
	if (fabs((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) <= EPS)
	{
		return 0;
	}
	else if (((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) > EPS)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

void TestStruct()
{
	Stu stu[3] = { {"bb",10,300},{"aa",30,200},{"cc",20,100} };
	int sz = sizeof(stu) / sizeof(stu[0]);
	qsort(stu, sz, sizeof(stu[0]), CmpStructName);
	qsort(stu, sz, sizeof(stu[0]), CmpStructAge);
	qsort(stu, sz, sizeof(stu[0]), CmpStructTotal);
}

int main()
{
	TestInt();
	TestChar();
	TestFloat();
	TestStruct();
	return 0;
}

qsort的实现(用冒泡排序)

写法一

void Swap(char* buf1, char* buf2, int size)//交换arr[j],arr[j+1]这两个元素
{
	int i = 0;
	char tmp = 0;
	for (i = 0; i < size; i++)
	{
		tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}

void bubble_sort(void* base, int num, int size, int (*cmp)(const void*, const void*))
{
	int  i = 0;
	//趟数
	for (i = 0; i < num - 1; i++)
	{
		int j = 0;
		//一趟内部比较的对数
		for (j = 0; j < num - 1 - i; j++)
		{
			//假设需要升序cmp返回>0,交换
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)//两个元素比较,需要将arr[j],arr[j+1]的地址要传给cmp
			{
				//交换
				Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}

}

写法二

void Swap(void* base, int j, size_t size)
{
	int i = 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *((char*)base + j * size + i);
		*((char*)base + j * size + i) = *((char*)base + (j+1) * size + i );
		*((char*)base + (j+1) * size + i) = tmp;
	}
}

void BubbleSort(void* base, size_t num, size_t size, int (*compar)(const void*, const void*))
{
	int i = 0;
	for (i = 0; i < num - 1; i++)
	{
		int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			
			if (compar(((char*)base + j * size), ((char*)base + (j + 1) * size)) > 0)
			{
				Swap(base,j,size);
			}
		}
	}
}

完整代码

#define _CRT_SECURE_NO_WARNINGS 1

//库函数qsort的实现(用冒泡排序的思想)
//void qsort (void* base, 
			// size_t num, 
			// size_t size,
			// int (*compar)(const void*, const void*));
//char int float struct

#include
#include//BubbleSort
#include//fabs//绝对值

#define EPS 1e-7 //判断浮点数是否位于0的一个很小的邻域内[-EPS,EPS]内

typedef struct STU
{
	char name[10];
	int age;
	float TotalScore;
}Stu;

//写法一
//void Swap(char* buf1, char* buf2, int size)//交换arr[j],arr[j+1]这两个元素
//{
//	int i = 0;
//	char tmp = 0;
//	for (i = 0; i < size; i++)
//	{
//		tmp = *buf1;
//		*buf1 = *buf2;
//		*buf2 = tmp;
//		buf1++;
//		buf2++;
//	}
//}
//
//void bubble_sort(void* base, int num, int size, int (*cmp)(const void*, const void*))
//{
//	int  i = 0;
//	//趟数
//	for (i = 0; i < num - 1; i++)
//	{
//		int j = 0;
//		//一趟内部比较的对数
//		for (j = 0; j < num - 1 - i; j++)
//		{
//			//假设需要升序cmp返回>0,交换
//			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)//两个元素比较,需要将arr[j],arr[j+1]的地址要传给cmp
//			{
//				//交换
//				Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
//			}
//		}
//	}
//
//}

//写法二
void Swap(void* base, int j, size_t size)
{
	int i = 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *((char*)base + j * size + i);
		*((char*)base + j * size + i) = *((char*)base + (j+1) * size + i );
		*((char*)base + (j+1) * size + i) = tmp;
	}
}

void BubbleSort(void* base, size_t num, size_t size, int (*compar)(const void*, const void*))
{
	int i = 0;
	for (i = 0; i < num - 1; i++)
	{
		int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			
			if (compar(((char*)base + j * size), ((char*)base + (j + 1) * size)) > 0)
			{
				Swap(base,j,size);
			}
		}
	}
}

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

void TestInt()
{
	int arr[] = { 7,5,9,1,3,2,4,6,8,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	BubbleSort(arr, sz, sizeof(arr[0]), CmpInt);
}

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

void TestChar()
{
	char arr[] = "AKRZXIY";
	int sz = sizeof(arr) / sizeof(arr[0]);
	BubbleSort(arr, sz, sizeof(arr[0]), CmpChar);
}

int CmpFloat(const void* p1, const void* p2)
{
	if (fabs((*(float*)p1 - (*(float*)p2)) <= EPS))
	{
		return 0;
	}
	else if ((*(float*)p1 - (*(float*)p2) > EPS))
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

void TestFloat()
{
	float arr[] = { 1.2f,3.4f,2.8f,8.4f,6.3f };
	int sz = sizeof(arr) / sizeof(arr[0]);
	BubbleSort(arr, sz, sizeof(arr[0]), CmpFloat);
}

int CmpStructName(const void* p1, const void* p2)
{
	return strcmp((*(Stu*)p1).name, (*(Stu*)p2).name);
}

int CmpStructAge(const void* p1, const void* p2)
{
	return ((*(Stu*)p1).age - (*(Stu*)p2).age);
}

int CmpStructTotal(const void* p1, const void* p2)
{
	if (fabs((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) <= EPS)
	{
		return 0;
	}
	else if (((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) > EPS)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

void TestStruct()
{
	Stu stu[3] = { {"bb",10,300},{"aa",30,200},{"cc",20,100} };
	int sz = sizeof(stu) / sizeof(stu[0]);
	BubbleSort(stu, sz, sizeof(stu[0]), CmpStructName);
	BubbleSort(stu, sz, sizeof(stu[0]), CmpStructAge);
	BubbleSort(stu, sz, sizeof(stu[0]), CmpStructTotal);
}

int main()
{
	TestInt();
	//TestChar();
	//TestFloat();
	//TestStruct();
	return 0;
}

你可能感兴趣的:(c语言,#,知识点,c语言)