使用冒泡排序讲解函数指针
来源:互联网 发布:e4a连接数据库 编辑:程序博客网 时间:2024/06/06 17:02
指针不光可以指向数组,整型变量等data objects, 在C里面,指针也可以指向函数,指向函数的
指针有很多种用处,下面举例说明。
思考下面的问题,你想实现一个函数可以对任意数据类型进行排序,比如说,字符串,整数,浮点
数,甚至是结构体。具体的算法都用一样的,可以是冒泡排序,当然也可以是更复杂一些的算法,
比如 shell 或者快速排序。 为了演示,我们在这里使用简单的冒泡排序。
Sedgewick 有描述过怎样用C语言来实现冒泡排序,假设我们把函数名叫bubble(), 它可以是这个样
子的。 bubble1.c,
#include <stdio.h>int arr[10] = { 3, 6, 1, 2, 3, 8, 4, 1, 7, 2};void bubble(int a[], int N);int main(void){ int i; putchar('\n'); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } bubble(arr, 10); putchar('\n'); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } system("pause"); return 0;}void bubble(int a[], int N){ int i, j, t; for (i = N-1; i >= 0; i--) { for (j = 1; j <= i; j++) { if (a[j-1] > a[j]) { t = a[j -1]; a[j-1] = a[j]; a[j] = t; } } }}
冒泡排序是一种比较简单的排序,这种算法扫描从第二到到最后一个,使用每一个元素和它之前的
那个元素比,如果前一个比当前元素要大,那么交换它们,这样,比较大的那一个就越来越靠近
数组的末尾,第一轮循环结束,最大的那个数将会移动到数组的末尾,下一轮循环将把第二大的
数列在最大的那个数前面,这样重复(元素个数减1)次,就会得到一个有序数组。
这里我们的函数有很大的局限性,只能比较整型数组里面的数据,为了能够比较任意类型,我们
先把比较这个过程从bubble()中拿出来,程序是这个样子的。
/* Separating the comparison function */#include <stdio.h>int arr[10] = { 3, 6, 1, 2, 3, 8, 4, 1, 7, 2};void bubble(int a[], int N);int compare(int m, int n);int main(void){ int i; putchar('\n'); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } bubble(arr,10); putchar('\n'); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } system("pause"); return 0;}void bubble(int a[], int N){ int i, j, t; for (i = N-1; i >= 0; i--) { for (j = 1; j <= i; j++) { if (compare(a[j-1], a[j])) { t = a[j-1]; a[j-1] = a[j]; a[j] = t; } } }} int compare(int m, int n){ return (m > n);}
如果我们的目的是可以排任意类型的数据,有一种搞法是这样的,使用void 指针,而不使用整型
数据类型,作为这个方向的开始,我们对上面函数作一些简答的修改,这里我们将指针指整型数据。
#include <stdio.h>int arr[10] = { 3, 6, 1, 2, 3, 8, 4, 1, 7, 2 };void bubble(int *p, int N);int compare(int *m, int *n);int main(void){ int i; putchar('\n'); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } bubble(arr, 10); putchar('\n'); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } system("pause"); return 0;}void bubble(int *p, int N){ int i, j, t; for (i = N-1; i >= 0; i--) { for (j = 1; j <= i; j++) { if (compare(&p[j-1], &p[j])) { t = p[j-1]; p[j-1] = p[j]; p[j] = t; } } }}int compare(int *m, int *n){ return (*m > *n);}
注意我们修改到我地方,这里我们向bubble() 传递了一个指向integer的指针,下一步里,我们
将使用指向void 类型的指针,这样函数对数据类型变得更加的不敏感。
#include <stdio.h>#include <stdio.h>int arr[10] = {3, 6, 1, 2, 4, 8, 4, 1, 7, 2};void bubble(int *p, int N);int compare(void *m, void *n);int main(void){ int i; putchar('\n'); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } bubble(arr, 10); putchar('\n'); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } system("pause"); return 0;}void bubble(int *p, int N){ int i, j, t; for (i = N-1; i >= 0; i--) { for (j = 1; j <= i; j++) { if (compare((void *)&p[j-1], (void *) &p[j])) { t = p[j - 1]; p[j-1] = p[j]; p[j] = t; } } } }int compare(void *m, void *n){ int *m1, *n1; m1 = (int *)m; n1 = (int *)n; return (*m1 > *n1);}我们知道,数据的名字是一个指向其第一个元素(在数据段)地址的指针,同样的道理,函数名将指向函数代码
段的开始的地址。
指向函数的指针必须和函数参数的类型,个数以及返回值匹配,在这里我们这样定义
我们的函数指针:
int (*fptr)(const void *p1, const void *p2);
注意不能写成这样:
int *fptr(const void *p1, const void *p2);
如果写成这样,它的意思是给出了一个函数原型,它将返回一个指向int 的指针。这是因为
在C语言中括号() 比 * 的优先级要高。在* fptr 打个括号表示我们声明了一个函数指针。
这里我们修改一下bubble()的声明,增加第四个参数,一个指向合适类型的函数指针。
它的函数原型将变成这个样子:
void bubble(void *p, int width, int N, int (*fptr)(const void *, const void *));
当我们调用bubble的时候,将我们希望使用的比较函数名插进去。下面程序将会阐明这样方法的实现。
#include <stdio.h>#include <string.h>#define MAX_BUF 256long arr[10] = {3, 6, 1, 2, 3, 8, 4, 1, 7, 2};char arr2[5][20] = { " Mickey Mouse", " Donald Duck", " Minnie Mouse", " Goofy", " Ted Jensen" }; void bubble(void *p, int width, int n, int (*fptr)(const void *, const void *));int compare_string(const void *m, const void *n);int compare_long(const void *m, const void *n); int main(void){ int i; puts("\nBefore Sorting:\n"); for (i = 0; i < 10; i++) /* show the long ints */ { printf("%ld ", arr[i]); } puts("\n"); for (i = 0; i < 5; i++) { printf("%s\n", arr2[i]); /* show the strings */ } bubble(arr, 4, 10, compare_long); /* sort the longs */ bubble(arr2, 20, 5, compare_string); /* sort the strings */ puts("\n\nAfter Sorting:\n"); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } puts("\n"); for (i = 0; i < 5; i++) /* show the sorted strings */ { printf("%s\n", arr2[i]); } system("pause"); return 0;}void bubble(void *p, int width, int N, int (*fptr)(const void *, const void *)){ int i, j, k; unsigned char buf[MAX_BUF]; unsigned char *bp = p; for (i = N - 1; i >= 0; i--) { for (j = 1; j <= i; j++) { k =fptr((void *)(bp + width*(j-1)), (void *)(bp + j *width)); } if (k > 0) { memcpy(buf, bp + width*(j-1), width); memcpy(bp + width*(j-1), bp + j*width, width); memcpy(bp + j*width, buf, width); } }}int compare_string(const void *m, const void *n){ char *m1 = (char *)m; char *n1 = (char *)n; return (strcmp(m1,n1));}int compare_long(const void *m, const void *n){ long *m1, *n1; m1 = (long *)m; n1 = (long *) n; return (*m1 > *n1); }
- 使用冒泡排序讲解函数指针
- 使用函数指针的多功能冒泡排序
- 冒泡排序-函数指针
- 冒泡排序与函数指针.
- 冒泡排序详细讲解
- 冒泡排序法 讲解
- 冒泡排序-指针交换
- 指针实现冒泡排序
- c++指针冒泡排序
- 冒泡排序(C指针)
- 指针函数和冒泡排序法算法案例
- 冒泡排序之逐步讲解
- 冒泡排序的例题讲解
- 函数指针作为函数参数,实现冒泡排序的升序排序和降序排序
- 函数指针的应用比较排序与冒泡排序指针完成
- 输入三个数字使用指针进行排序(冒泡原理)
- 使用冒泡排序模仿Qsort函数对不同数据排序
- 函数指针讲解
- iOS应用程序内存调试的代码的分析
- Spring源码学习一_下载Spring项目源码并编译为Eclipse
- 【写给程序员】请不要做浮躁的人
- HDU 3068 最长回文(manacher算法:回文字串)
- php面试题集-数据库技术题
- 使用冒泡排序讲解函数指针
- php面试题集-综合技术题
- JavaScript学习记录——《学用 JavaScript 设计模式》学习笔记(2)单例模式
- php面试题集-前端技术题
- 深度学习(Deep Learning,DL)的相关资料总结
- C与C++混合编程
- 一个较完整的IPhone秒表程序
- 关于Qrcode和zxing的一些看法
- 超快速编写ejb3.0的实体bean