qsort与bubble之间不为人知的关系

文章目录

  • 1.qsort函数详解
    • 1.1void*用法的引入
    • 1.2函数定义
    • 1.3各类数据的cmp函数
    • 1.4qsort函数应用
  • 2.模仿qsort实现通用冒泡排序
    • 1.1法一:充分利用内存函数
    • 1.2法二:充分体验库函数底层原理

1.qsort函数详解

作为C语言无理快排函数,学到就是赚到,啦啦啦~

1.1void*用法的引入

1.可以存放任意类型地址(指针)
2.无法进行解引用操作和指针运算。(不知道访问几个字节。)

1.2函数定义

void qsort
(
	       void* base,        待排数据首对象地址
	       size_t num,        排序数据元素个数
           size_t size,       排序数据中一个元素大小,单位字节
	int (*cmp) (const void*, const void*) 指向一个比较函数的指针(自定义)
); 

1.3各类数据的cmp函数

intint cmp_int(const void* a, const void* b)
{
	return *(int*)a - *(int*)b;
}
floatint cmp_float(const void* e1,const void* e2)
{
	return (int)(*(float*)e1 - *(float*)e2);
}
字符串大小
int cmp_str_size(const void* e1, const void* e2)
{
	return strcmp((char*)e1, (char*)e2);
}
字符串长度
int cmp_str_1en(const void* e1,const void* e2)
{
	return strlen((char*)e1) - strlen((char*)e2);
}

注意:

1.cmp函数的返回值:> 0 (进行置换) <= 0 (不进行置换)
2.返回结果 :确保整形,若不是,则强制类型转换成整形!

1.4qsort函数应用

typedef struct Stu
{
	char name[20];
	int age;
}S;
void print_arr(int arr[], int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ",arr[i]);
		printf("\n");
	}
}
int sort_by_age(const void* a, const void* b)
{
	return ( ( (S*)a )->age - ( ( (S*)b) ) ->age);
}
int sort_by_name(const void* a, const void* b)
{
	return strcmp(((S*)a)->name, ((S*)b)->name);
}
int main()
{
	int a[10] = { 9,8,7,6,5,4,3,2,1,0 };
	S s[3] = { {"zhangsan", 30}, {"lisi", 34}, {"wangwu", 20} };
	int sz_a = sizeof(a) / sizeof(a[0]);
	int sz_s = sizeof(s) / sizeof(s[0]);
	//qsort(a, sz_a, sizeof(a[0]), cmp_int);     //整形数组排序
	//qsort(s, sz_s,sizeof(s[0]), sort_by_age);  //按年龄排序
	//qsort(s, sz_s, sizeof(s[0]), sort_by_name);//按名字排序
	//print_arr(a, sz_a);
	return 0;
}

2.模仿qsort实现通用冒泡排序

1.1法一:充分利用内存函数

int cmp(const void* a, const void* b)
{
	return *(int*)a - *(int*)b;
}
void my_qsort(void* A, size_t n, size_t m, int(*cmp)(const void*, const void*))
{                //a        10         4
	char* a = (char*)A;
	char t[16];
    for (int i = 0; i < n - 1; i++)
	{     
		for (int j = 0; j < n - 1 - i; j++)
		{   
			//此语句功能:交换所比较的两个数字
			if (cmp(a + j * m, a + (j + 1) * m))
			{
				memcpy(t, a + j * m, m);
				memcpy(a + j * m, a + (j + 1) * m, m);
				memcpy(a + (j + 1) * m, t, m);
			}
		}
	}
}
int main()
{
	int a[10] = { 9,8,7,6,5,4,3,2,1,0 };
	my_qsort(a, 10, 4, cmp); 
	for (int i = 0; i < 10; i++)
		printf("%d ", a[i]);
    return 0;
}

1.2法二:充分体验库函数底层原理

int cmp_int(const void* a, const void* b)
{
	return *(int*)a - *(int*)b;
}
void print_arr(int arr[], int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
		printf("\n");
	}
}
void Swap(char* a, char* b, int width)
{
	for (int i = 0; i < width; i++)
	{
		char t = *a;
		*a = *b;
		*b = t;
		a++;
		b++;
	}
}
void bubble_sort
(
	void* base,
	int sz,
	int width,
	int (*cmp) (const void* e1, const void* e2)
)
{
	for (int i = 0; i < sz - 1; i++)
	{
		for (int j = 0; j < sz - 1 - i; j++)
		{
			if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) )
				Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
		}
	}
}
int main()
{
	int arr[] = { 1,3,5,7,9,2,4,6,8,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz, sizeof(arr[0]),cmp_int);
	print_arr(arr, sz);
	return 0;
}

你可能感兴趣的:(呕心沥血C语言,数据结构,算法,排序算法)