回调函数实现冒泡法的多种排序

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
typedef struct//定义学生结构体
{
	char name[20];
	char number[20];
	int score;
}Student;

int struct_cmp(const void *elem1, const void *elem2)
{
	assert(elem1);
	assert(elem2);//断言
	return ((*(Student*)elem1).score - (*(Student*)elem2).score);//通过比较student的分数确定大小
}
int int_cmp(const void *elem1, const void *elem2)//整型比较函数
{
	assert(elem1);
	assert(elem2);//断言
	return (*(int *)elem1 - *(int *)elem2);
	//elem1和elem2为两个int变量的地址,所以将elem1和elem2强制类型转换为int*类型,
	//然后截引用,访问两个int 变量,返回值为两个int 变量的差,如果第一个数大于第二个
	//返回整数,相等返回0,小于返回负数。
}

int str_cmp(const void *elem1, const void *elem2)
{
	assert(elem1);
	assert(elem2);//断言
	return strcmp((char*)*(int *)elem1,(char*)*(int *)elem2);
	//elem1和elem2为存放字符串地址的字符指针,所以需要访问4个字节,
	//将其强制类型转换为int*,然后截引用访问到字符串指针,最后将其强制类型转换为(char *).
}

void swp(void *elem1, void *elem2, size_t width)//size_t width为类型所占的空间,由于不知道交换的是什么类型,
                                                //所以需要多传入一个参数(表示类型的大小),然后以字节为单位逐个交换
{
	assert(elem1);
	assert(elem2);//断言
	size_t i = 0;
	//逐字节的交换,进而交换两个变量
	for (i = 0; i < width; i++)
	{
		char tmp = *((char*)elem1 + i);
		*((char*)elem1 + i) = *((char*)elem2 + i);
		*((char*)elem2 + i) = tmp;
	}
}
void bubble(void *arr, size_t num, size_t width, int(*compare)(const void *elem1, const void *elem2))
                                                   //int(*compare)(const void *elem1, const void *elem2为一个比较函数指针
{
	assert(arr);
	assert(compare);//断言
	size_t i = 0, j = 0;
	for (i = 0; i < num - 1; i++)
	{
		for (j = 0; j < num - 1 - i; j++)
		{
			if (compare(((char*)arr + j*width), (char*)arr + (j + 1)*width)>0)//由于不知道需要比较的函数类型,所以利用类型的大小作为函数参数,
				                                                               //并统一转换为(char *)进行逐字节的转换(char*)arr + j*width
			{
				swp((char*)arr + j*width, (char*)arr + (j + 1)*width, width);
			}
		}
	}
}

int main()
{
	char *arr1[] = { "amdgdj","lsansk","aaaaa","ueojjfdh","dcsaouid" };
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	bubble(arr1, sz, sizeof(arr1[0]), str_cmp);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%s\n", arr1[i]);
	}

	int arr2[] = { 1,3,7,7,6,4,9,4,3,8,5 };
	sz = sizeof(arr2) / sizeof(arr2[0]);
	bubble(arr2, sz, sizeof(arr2[0]), int_cmp);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr2[i]);
	}
	printf("\n");

	Student arr3[] = { {"张三","201312030120",94},{"李四","201312030118",98},{"王麻子","201312030116",96} };
	sz = sizeof(arr3) / sizeof(arr3[0]);
	bubble(arr3, sz, sizeof(arr3[0]), struct_cmp);
	for (i = 0; i < sz; i++)
	{
		printf("%s %s %d\n", arr3[i].name, arr3[i].number, arr3[i].score);
	}
	system("pause");
	return 0;
}

时间: 2024-12-25 07:28:34

回调函数实现冒泡法的多种排序的相关文章

冒泡法排序_c++实现

看完了郝斌老师的c语言视频,冒泡法排序,就试着写了.我觉得学习算法最重要的不是代码,而是它的原理. 代码: 1 /** 2 * Copyright (c) 1991 - 2016 Arvin Tang. 3 * All rights reserved. 4 * 5 * 文件名称:郝斌C语言视频教程_163_冒泡排序 6 * 简要描述:用冒泡法排序 7 * 8 * 当前版本:1.0 9 * 作 者: 10 * 完成日期:2016-1-9 11 * 修订说明: 12 * 13 * 取代版本: 14

使用函数指针,完成一个sort()函数,能对任何类型的数组元素进行排序: 回调函数 以及 memcpy ()原型实现

进来复习了一下C语言指针,一直没有写过太多关于函数指针的代码,而且对回调函数的理解一直都是在理论上,基本上没有太写过关于它的代码,进来得空,写了一个小程序加深下自己对回调函数和函数指针的理解. 问题描述: 编写一个sort()函数,使它能够对任何类型的数组元素进行排序. 下面是我写的代码: /* 使用函数指针的回调函数技巧,设计一个能排序int 和char 数组的sort()函数 */ #include<stdio.h> #include<stdlib.h> #include<

回调函数之感想

回调函数的问题一直困扰我,网上也是众说纷纭,却一直不能解决我的困惑. 1.回调函数的意义是: 当你想要别人的代码执行你的代码时,而你又不能修改别人代码.(网上有人这么说) 加入我个人的理解,这里的不能修改应该是指,你不能去干涉别人代码,但是可以协商或者提出需求说 我需要一个接口,在你完成XX操作后,调用我的DoXX函数,这时,大家都会想到一个方法,直接让别人的代码执行DoXX函数,不就ok了? 我也在困惑- ,今天看到了这个说法,回调函数的实现可以有多种,别人代码直接调用你的方法也ok,但是在软

c/c++:回调函数

1:函数名为指针 首先,在C语言中函数是一种function-to-pointer的方式,即对于一个函数,会将其自动转换成指针的类型.如: 1 #include<stdio.h> 2 3 void fun() 4 { 5 } 6 7 int main() 8 { 9 printf("%p %p %p\n", &fun, fun, *fun); 10 return 0; 11 } 这三个值的结果是一样的. 其实对于最后的那个*fun, 即使前面加上很多个*号, 其结果

第十三周项目4——数组的排序(冒泡法)

/* * Copyright (c) 2014, 烟台大学计算机学院 * All rights reserved. * 文件名称:test.cpp * 作    者:李晓凯 * 完成日期:2014年 11 月 29日 * 版 本 号:v1.0 * * 问题描述:降序排列数组的数并输出 * 输入描述: * 程序输出:降序排列数组的数并输出 */ #include <iostream> using namespace std; void bubble_sort(int a[],int n); vo

排序算法(交换法,选择法,插入排序,冒泡法,快速排序算法,C语言举例)

交换法:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动. 简单选择排序:的基本思想:第1趟,在待排序记录r[1]~r[n]中选出最小的记录,将它与r[1]交换;第2趟,在待排序记录r[2]~r[n]中选出最小的记录,将它与r[2]交换;以此类推,第i趟在待排序记录r[i]~r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕. 插入排序法:有一个已经有序的

数组的排序,冒泡法,快速排序法

1.冒泡法排序 /* * 冒泡法排序 :在要排序的一组数中,对当前还未排好序的范围内的全部数,自左而右对相邻的两个数 * 相邻的两个数的交换 */ public void bubbleSort(int[] num) { int temp = 0; for(int i=0;i<num.length-1;i++){ for(int j=0;j<num.length-1-i;j++){ if(num[j]>num[j+1]){ temp=num[j]; num[j]=num[j+1]; num

8. 冒泡法排序和快速排序(基于openCV)

一.前言 主要讲述冒泡法排序和快速排序的基本流程,并给出代码实现,亲测可用. 二.冒泡法排序 冒泡法排序主要是将相邻两个值比较,把小的向前冒泡,大的向后沉淀,时间复杂度为O(n2).主要思想如下: 分为内外循环,每次外循环确定一个大的数据的具体位置,如下实例: 从图中可以看出,进过两次外循环就可以得到排序结果,随后的8次循环都浪费了,为了避免这种情况,我们可以设置一个状态参数,用来表示内循环是否发生数据的交换,从而作为外循环是否退出的信号. 三.快速排序 快速排序是最有效的排序方法之一,其主要思

关于回调函数 usort() uksrot() sort() 介绍简介【实验是从小到大排序】

/* * usort($arr, "自定义回调函数") 对数组中的值进行比较  */    $a=array(1,5,2,6,3);    //用户自定义回调函数     function dd($a, $b){    //用户自定义回调函数         if($a == $b){            return 0;       //如果两个参数相等,返回0         }        return ($a<$b)?-1:1;  //如果第1个参数大于第2个返回1