C进阶:指针(2),qsort函数,模拟实现冒泡算法(下)

简介: C进阶:指针(2),qsort函数,模拟实现冒泡算法(下)

cmp_int 函数解释:

三.模拟实现冒泡算法

1.什么是冒泡排序

冒泡排序

冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。

过程演示:

图解:

下面来看一个实例:

1. void bubble_sort(int arr[], int len)
2.  {
3. int i, j, temp;
4. for (i = 0; i < len - 1; i++)    //确定趟数
5.     {
6. for (j = 0; j < len - 1 - i; j++)  //对一趟进行冒泡排序
7.         {
8. if (arr[j] > arr[j + 1]) 
9.             {
10.                 temp = arr[j];
11.                 arr[j] = arr[j + 1];
12.                 arr[j + 1] = temp;
13.             }
14.         }
15.     }
16. }
17. int main() 
18. {
19. int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
20. int len = (int) sizeof(arr) / sizeof(*arr);
21. bubble_sort(arr, len);
22. int i;
23. for (i = 0; i < len; i++)
24. printf("%d ", arr[i]);
25. return 0;
26. }

其实我们会发现,上面这种方法有一定的局限性,它只能排整型数据,那我们可不可以写一个类似于冒泡排序算法的函数来实现可以排序任何数据呢?

这就需要利用到回调函数了

2.模拟实现冒泡算法

通过上文我们知道,qsort 是一个可以快速排序的库函数,它使用起来很方便,那么我们就可以模仿 qsort 函数的定义来实现 一个可以排任何数据的冒泡函数 bubble_sort;

函数名有了,接下来就是函数参数和返回值的设计了,仿照 qsort ,我们可以这么设计:

void bubble ( void*base , size_t  sz  ,size_t  width, void (*cmp) (const void * ,const void * )

1.第一个参数 是指向要排序的数组的第一个元素的指针;

2.第二个参数 是数组元素的个数;

3.第三个参数 是数组每个元素的大小,也可以理解成宽度,单位是字节;

4.第四个参数 是一个函数指针,且需要我们自己设计

那么这个函数要怎么设计呢?

我们知道冒泡排序是两个相邻元素之间的比较,所以说在设计函数参数时,参数应该指向的是数组中两个相邻的元素,可是我们在设计函数时并不知道参数的具体类型,又该怎么向函数传数组中的两个相邻元素呢?

请看下图:

两个相邻的元素找到了,下面就是交换了

交换就需要创建一个中间变量,可是我们并不知道要交换的两个数据的类型,那自然就不知道该怎么定义中间变量的类型,但是众所周知,所有的数据类型中 char 是最小的,只占1个字节,那么其他的数据类型我们都可以看成是由若干个 char 组成的,所以我们可以定义一个 char 变量来作为中间变量,然后对数据进行一个一个字节的交换,交换终止的条件由 width 决定,所以我们定义的 width 也要传到交换函数里面去。

具体代码:

1. void Swap(char* buf1, char* buf2, int width)  
2. {
3.  int i = 0;
4.  for (i = 0; i < width; i++)  //循环由 width 控制
5.  {
6.    char tmp = *buf1;   //一个一个字节进行交换
7.    *buf1 = *buf2;
8.    *buf2 = tmp;
9.    buf1++;      //一个字节交换完后 ,buf1++ buf2++,再进行下一轮的字节交换
10.     buf2++;
11.   }
12. }

实例:

1. int cmp_int(const void* e1, const void* e2)
2. {
3.  return *((int*)e2) - *((int*)e1);
4. } 
5. //交换函数
6. void Swap(char* buf1, char* buf2, int width)
7. {
8.  int i = 0;
9.  for (i = 0; i < width; i++)
10.   {
11.     char tmp = *buf1;
12.     *buf1 = *buf2;
13.     *buf2 = tmp;
14.     buf1++;
15.     buf2++;
16.   }
17. }
18. //模拟实现冒泡算法,并使它可以排任何类型的数据
19. void bubble_sort(void* base, int sz, int width, int (*cmp)(const void* e1, const void* e2))
20. {
21.   int i = 0, j = 0;
22.   for (i = 0; i < sz - 1; i++)  //确定趟数
23.   {
24.     for (j = 0; j < sz - 1 - i; j++) //一趟比较
25.     {
26.       if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
27.       {
28.         Swap((char*)base + j * width, (char*)base + (j + 1) * width, width); //交换
29.       }
30.     }
31.   }
32. }
33. //打印数组
34. void print(int arr[], int sz)
35. {
36.   int i = 0;
37.   for (i = 0; i < sz; i++)
38.   {
39.     printf("%d ", arr[i]);
40.   }
41.   printf("\n");
42. }
43. void test4()
44. {
45.   int arr[10] = { 1,3,5,7,9,2,4,6,8,10 };
46.   int sz = sizeof(arr) / sizeof(arr[0]);
47.   bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
48.   print(arr, sz);
49. }
50. int main()
51. {
52.   test4();
53.   return 0;
54. }

运行结果:

  😸😼本篇文章到此就结束啦,如有错误或是建议,欢迎小伙伴们指出。🐆🐅

  😻😽谢谢你的阅读。🦖🦄                


目录
相关文章
|
2月前
|
搜索推荐 Python
利用Python内置函数实现的冒泡排序算法
在上述代码中,`bubble_sort` 函数接受一个列表 `arr` 作为输入。通过两层循环,外层循环控制排序的轮数,内层循环用于比较相邻的元素并进行交换。如果前一个元素大于后一个元素,就将它们交换位置。
138 67
|
2月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
60 4
|
3月前
|
存储 C语言 C++
如何通过指针作为函数参数来实现函数的返回多个值
在C语言中,可以通过将指针作为函数参数来实现函数返回多个值。调用函数时,传递变量的地址,函数内部通过修改指针所指向的内存来改变原变量的值,从而实现多值返回。
|
3月前
|
存储 搜索推荐 C语言
如何理解指针作为函数参数的输入和输出特性
指针作为函数参数时,可以实现输入和输出的双重功能。通过指针传递变量的地址,函数可以修改外部变量的值,实现输出;同时,指针本身也可以作为输入,传递初始值或状态。这种方式提高了函数的灵活性和效率。
|
3月前
|
C++
指针中的回调函数与qsort的深度理解与模拟
本文详细介绍了回调函数的概念及其在计算器简化中的应用,以及C++标准库函数qsort的原理和使用示例,包括冒泡排序的模拟实现。
26 1
|
3月前
利用指针函数
【10月更文挑战第2天】利用指针函数。
22 1
|
3月前
|
算法 搜索推荐 C语言
【C语言篇】深入理解指针4(模拟实现qsort函数)
【C语言篇】深入理解指针4(模拟实现qsort函数)
30 2
|
4月前
|
算法 索引 容器
双指针算法详解
本文介绍了双指针算法及其应用。双指针算法是在数组或字符串中常用的高效技术,通过维护两个指针遍历数据结构以解决特定问题。根据指针移动方向,可分为同向双指针、相向双指针和快慢指针。同向双指针如移动零和复写零问题;快慢指针如快乐数问题;相向双指针如盛水最多的容器、有效三角形数量及多数之和等问题。通过合理运用双指针技巧,可简化代码并提高效率。
81 4
|
4月前
|
XML JavaScript 前端开发
学习react基础(1)_虚拟dom、diff算法、函数和class创建组件
本文介绍了React的核心概念,包括虚拟DOM、Diff算法以及如何通过函数和类创建React组件。
42 3
|
3月前
|
数据可视化 搜索推荐 Python
Leecode 刷题笔记之可视化六大排序算法:冒泡、快速、归并、插入、选择、桶排序
这篇文章是关于LeetCode刷题笔记,主要介绍了六大排序算法(冒泡、快速、归并、插入、选择、桶排序)的Python实现及其可视化过程。
25 0