qsort 排序和 bsearch 查找

qsort 排序

<stdlib.h> 中的实用函数 http://www.cplusplus.com/reference/cstdlib/
有些口水话说得不够准确,欢迎指正


    void* 无类型指针 后面常跟强制类型转换操作

    qsort 排序 :
    void qsort (void* base, size_t num, size_t size,
                int (*compar)(const void*,const void*));
    void* 无类型指针 传入类型是数组;size_即int型;num 数组大小;size数组中每个元素的大小

    qsort 排序和 bsearch 二分查找的配合
    eg: 必须根据总分排序,才能后续查找有某总分的结构体


bsearch 查找


    void* 无类型指针 后面常跟强制类型转换操作

    bsearch 二分查找(前提是数组已经从 大到小/小到大 排序,即在 qsort()后调用 bsearch()):
    void* bsearch (const void* key, const void* base, size_t num, size_t size,
                   int (*compar)(const void*,const void*));
    const void* base 无类型指针 传入类型是数组;const void* key 要查找的数字/字符
    函数返回的是所找到元素所在结构体的地址(指针)

    qsort 排序和 bsearch 二分查找的配合
    eg: 必须根据总分排序,才能后续查找有某总分的结构体


学生成绩排序并查找

mark.txt
Tom 97 68 45
Jerry 100 32 88
Harry 78 88 78
Lucy 87 90 89
Mickey 88 77 66
Peter 59 68 98
Alice 62 73 89


#include <stdio.h>      /* printf */
#include <stdlib.h>     /* qsort */

// 学生名单及成绩
typedef struct {
	char name[30];
	int Chinese;
	int Math;
	int English;
} Student;

// 学生数组
Student students[7];

void readData();  // 从文件中读取数据
void displayData();  // 输出学生数据
int compare(const void *a, const void *b); // qsort函数中调用了(内嵌了)compare函数,需要提前声明
int compare2(const void *key, const void *e); // bsearch函数调用(内嵌)

int main() {

	readData();
	qsort(students, 7, sizeof(Student), compare);

	int key = 224;
	// bsearch函数返回找到的元素所在结构体的指针
	Student *s = bsearch(&key, students, 7, sizeof(Student), compare2);
	printf("%s\n", s->name);

	displayData();

	return 0;
}

// qsort函数内嵌函数
int compare(const void *a, const void *b) {

	// 强制类型转换为Student结构体型指针
	Student *pa = (Student *)a;
	Student *pb = (Student *)b;

	// 取出指针所指实际值
	//int num1 = pa->Chinese ;  // 根据语文成绩排序
	//int num2 = pb->Chinese ;

	int num1 = pa->Chinese + pa->English + pa->Math ;  // 根据总成绩排序
	int num2 = pb->Chinese + pb->English + pb->Math;


	//return num1 - num2;  // 前-后 从小到大排序 qsort函数会将<0的返回值,转换为-1 定义为前<后
	return num2 - num1; // 后-前 从大到小排序  qsort函数会将>0的返回值,转换为1 定义为前>后


}

// bsearch 函数内嵌函数 e是结构体中元素,key是要查找的数字/字符
int compare2(const void *key, const void *e) {

	// void型指针 强制类型转换为对应数据指针
	int *pNum1 = (int *)key;
	Student *pS = (Student *)e;

	// 取出指针所指实际值
	int num1 = *pNum1;
	int num2 = pS->Chinese + pS->English + pS->Math;  // 根据总分查找

	return num2 - num1; // = 0 即找到了所需元素

}

void readData() {

	// FILE是在stdio.h定义的保存文件流信息的一个结构体类型,FILE*指向文件类型的指针
	FILE *file = fopen("mark.txt", "r");  // 打开文件

	int i;
	for (i = 0; i < 7; i++) {
		fscanf(file, "%s", students[i].name );  // 取数字需要&符号,取字符不用
		fscanf(file, "%d", &students[i].Chinese  );
		fscanf(file, "%d", &students[i].Math );
		fscanf(file, "%d", &students[i].English );
	}
	fclose(file);   // 关闭文件
}

void displayData() {

	int i;
	for (i = 0; i < 7; i++) {
		printf("%s\t", students[i].name );  
		printf("%d\t", students[i].Chinese  );
		printf("%d\t", students[i].Math );
		printf("%d\t", students[i].English );
		printf("%d\n", students[i].Chinese + students[i].Math + students[i].English );
	}
}


qsort 排序 int 型数组


#include <stdio.h>      /* printf */
#include <stdlib.h>     /* qsort */

int compare(const void *a, const void *b); // qsort函数中调用了(内嵌了)compare函数,需要提前声明

int main() {

	int arr[8] = {8, 2, 5, 4, 6, 7, 1, 2};
	qsort(arr, 8, sizeof(int), compare);

	int i;
	for (i = 0; i < 8; i++) {
		printf("%d\n", arr[i]);
	}

	return 0;
}

int compare(const void *a, const void *b) {

	// 强制类型转换为int型指针
	int *pa = (int *)a;
	int *pb = (int *)b;

	// 取出指针所指实际值
	int num1 = *pa;
	int num2 = *pb;

	return num1 - num2;  // 前-后 从小到大排序 qsort函数会将<0的返回值,转换为-1 定义为前<后
	//return num2 - num1; // 后-前 从大到小排序  qsort函数会将>0的返回值,转换为1 定义为前>后
}

qsort 排序 float 型数组


#include <stdio.h>      /* printf */
#include <stdlib.h>     /* qsort */


int compare(const void *a, const void *b); // qsort函数中调用了(内嵌了)compare函数,需要提前声明

int main() {

	float arr[8] = {8.0, 2., 5., 4., 6., 7., 1., 2.};
	qsort(arr, 8, sizeof(float), compare);

	int i;
	for (i = 0; i < 8; i++) {
		printf("%f\n", arr[i]);
	}

	return 0;
}

int compare(const void *a, const void *b) {

	// 强制类型转换为int型指针
	float *pa = (float *)a;
	float *pb = (float *)b;

	// 取出指针所指实际值
	float num1 = *pa;
	float num2 = *pb;

	/*
	return num1 - num2;  // 前-后 从小到大排序 qsort函数会将<0的返回值,转换为-1 定义为前<后
	//return num2 - num1; // 后-前 从大到小排序  qsort函数会将>0的返回值,转换为1 定义为前>后
	*/

	// qsort规定了内嵌的函数compare返回是int型,float值需要转换 否则无法返回
	if (num1 - num2 > 0) {
		return 1;
	} else {
		return -1;
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值