9.27 代码练习,以及教你写自己的qsort函数

news/2024/9/27 10:08:38

学生成绩系统代码

include <stdio.h>

typedef struct Student {
int num;
char name[50];
int grade[10];
} stu;

int cmp(int count[], int* n) {
int max=0;
for (int i = 0; i < *n; i++) {
if (count[i] > max)
{
max = count[i];
}
}
return max;
}

int main() {
int* n;
printf("输入几个人\n");
scanf("%d", n);

stu student[*n];
int count[*n];for (int i = 0; i < *n; i++) {printf("输入学号");scanf("%d", &student[i].num);printf("输入名字");scanf("%s", &student[i].name);printf("输入成绩");scanf("%d %d %d", &student[i].grade[0], &student[i].grade[1], &student[i].grade[2]);count[i] = (student[i].grade[0] + student[i].grade[1] + student[i].grade[2]) / 3;}int max = cmp(count, n);for (int i = 0; i < *n; i++) {if (count[i] == max){printf("%d %s %d", student[i].num, student[i].name, count[i]);}
}

}

用指针给随机数排最大

include <stdio.h>

include <stdlib.h>

include <time.h>

int n=10;

float imax(float arr) {
int max;
for(int i = 0; i < n; i++) {
if(
arr<*(arr+i))
{
arr=(arr+i);
}
}
return *arr;
}

int main() {

srand(time(NULL));float *arr;for(int i = 0; i < n; i++) {* (arr+i)=(float)rand()/RAND_MAX*10;
}for(int i = 0; i < n; i++) {printf("%f\n",*(arr+i));}float max=imax(arr);
printf("%f",max);
return 0;

}

qsort (quick sort)库函数的运用一:
比较各种类型的数组

include <stdio.h>

include <stdlib.h>

// 比较函数,用于确定排序顺序
int compare(const void *a, const void *b) { //void可以接收所有类型的指针,但是不能进行加减运算)
int *num1 = (int *)a;
int *num2 = (int *)b;
// double *num1 = (double *)a;
//double *num2 = (double )b;
// if (
num1 < num2) return -1;
// if (
num1 > *num2) return 1;
//return 0; (浮点类型也可以直接作差,但是遇到进度较高时不一定得出正确结果)
return *num1 - *num2; //从小到大
//return num2-num1,从大到小
}

int main() {
int arr[] = {5, 2, 8, 1, 9};
int n = sizeof(arr) / sizeof(arr[0]);

qsort(arr, n, sizeof(arr[0]), compare);printf("排序后的数组:");
for (int i = 0; i < n; i++) {printf("%d ", arr[i]);
}
printf("\n");return 0;

}

qsort (quick sort)库函数的运用二:
比较结构体类型的数组

include <stdio.h>

include <stdlib.h>

typedef struct {
int id;
char name[20];
} Student;

// 比较函数,按照学生的 id 进行升序排序
int compareStudents(const void *a, const void *b) {
Student *student1 = (Student *)a;
Student *student2 = (Student *)b;
return student1->id - student2->id;
}

int main() {
Student students[] = {
{3, "Alice"},
{1, "Bob"},
{2, "Charlie"}
};
int n = sizeof(students) / sizeof(students[0]);

qsort(students, n, sizeof(students[0]), compareStudents);printf("排序后的学生列表:\n");
for (int i = 0; i < n; i++) {printf("ID: %d, Name: %s\n", students[i].id, students[i].name);
}return 0;

}

用冒泡排序做一个qsort函数(全文的重点)

include <stdio.h>

//比较函数
int cmp(void *a,void *b,int size){
//为什么一定要转类型?因为不统一类型的话,你取void类型的地址,得到不知道几个字节大小的类型,无法进行比较
//因为从大到小,所以是b地址上的值减a地址上的值

return (*(int *)b) - (*(int *)a);
//不可以比较字符形和较细浮点类型(比如零点几的差异)//return (*(char *)b) - (*(char *)a);
//不可以比较浮点形//return memcmp((*(const char *)b),(*(const char *)a),size);
//因为memcmp是计算内存的差异,所以可以比较所有类型的元素差异,但是纯手搓的话可以试试不用库函数

}

//交换函数
//解引用后要进行多对字节的交换
void swap(char a,char b,int size){
for(int i=0;i<size;i++){
char temp=
a;
a=b;
b=temp;
a++;
b++;
//char tmp=
a+i;
//
a+i=b+i;
//
b+i=tmp;
}
}

//冒泡排序
//冒泡排序的框架是两个循环,内循环是输入两个相邻元素arr[j]和arr[j+1],用指针就是输入两个相邻元素的地址base+j和base+j+1
//想编程,数学题这种长链条的逻辑题,一定要知道自己在干什么,每一步在干什么,为什么这样干
//base:数组首地址,为什么是void *类型? 因为数组首地址是一个指针,但是不知道数组元素的类型,所以用void *类型
void bubble(void base,int len,int size,int (cmp)(void *e1,void *e2)){
for(int i=0;i<len-1;i++){
for(int j=0;j<len-1-i;j++){
if(cmp((char )base+jsize,(char )base+(j+1)size)>0){
//用base和base+1传参时,因为base是void 类型,无法运算,所以要强制转类型
//用base和(int
)base+1时,因为不知道base的类型,+1就加了4个字节(而浮点类型只要加2个字节,字符类型只要加1个字节),所以不能强制转为整形类型
//而当强制转为char *类型,char 类型的大小是1个字节,+1表示加一个字节,size是其类型的大小(每个元素的大小,单位是字节),加一个size就得到下一个元素的地址
//在char
类型中用+size统一了不同类型中“+1”的效果
//base是第一个元素的地址,(char *)base+size就是下一个个元素的地址,(char )base+jsize就是第j个元素的地址,(char )base+(j+1)size就是第j+1个元素的地址
//根本要求是传指针,上述解决的是+1导致的由于类型不同而增加字节数不同的问题

            swap((char *)base+j*size,(char *)base+(j+1)*size,size);}}
}

}

void test1(){
int arr1[]={1,2,3,4,5,6,7,8,9,10};
int len1=sizeof(arr1)/sizeof(arr1[0]);
int size1=sizeof(arr1[0]);
bubble(arr1,len1,size1,cmp);
for(int i=0;i<len1;i++){
printf("%d ",arr1[i]);
}
}

void test2(){
float arr2[]={1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.10};
int len2=sizeof(arr2)/sizeof(arr2[0]);
int size2=sizeof(arr2[0]);
bubble(arr2,len2,size2,cmp);
for(int i=0;i<len2;i++){
printf("%f ",arr2[i]);
}
}

void test3(){
char arr3[]={'a','b','c','d','e','f','g','h','i','j'};
int len3=sizeof(arr3)/sizeof(arr3[0]);
int size3=sizeof(arr3[0]);
bubble(arr3,len3,size3,cmp);
for(int i=0;i<len3;i++){
printf("%c ",arr3[i]);
}
}

struct student{
char name[20];
int age;
};

//test4
int cmp_name(void *a,void *b,int size){
return strcmp(((struct student *)a)->name,((struct student )b)->name);
//return strcmp((
(struct student )a).name,((struct student *)b).name);
}

void test4(){
struct student arr4[]={
{"张三",20},
{"李四",21},
{"王五",22},
{"赵六",23},
{"田七",24}
};
int len4=sizeof(arr4)/sizeof(arr4[0]);
int size4=sizeof(arr4[0]);

bubble(arr4,len4,size4,cmp_name);//因为是结构体,所以要新写一个可以比较名字的函数
for(int i=0;i<len4;i++){printf("%s ",arr4[i].name);
}

}

//test5
int cmp_age(void *a,void b,int size){
return (
(struct student )b).age-((struct student *)a).age;
}

void test5(){
struct student arr5[]={
{"张三",20},
{"李四",21},
{"王五",22},
{"赵六",23},
{"田七",24}
};
int len5=sizeof(arr5)/sizeof(arr5[0]);
int size5=sizeof(arr5[0]);

bubble(arr5,len5,size5,cmp_age);//因为是结构体,所以要新写一个可以比较年龄的函数
for(int i=0;i<len5;i++){printf(" %d ",arr5[i].age);
}

}

//&base.name

//主函数
int main(){

test1();
test2();
test3();
test4();
test5();return 0;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/65306.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

PbootCMS上传文件大小限制

要解决PBootCMS上传大文件的问题,需要从多个方面进行配置。以下是一个详细的步骤指南,包括修改php.ini文件、重启PHP服务、修改编辑器上传大小设置以及针对不同Web服务器的额外配置。 一、修改 php.ini 文件打开 php.ini 文件找到PHP安装目录下的 php.ini 文件。修改相关参数…

PbootCms内页打不开的常见情况汇总

在使用PBootCMS建站时,如果遇到内页无法正常访问的问题,通常与伪静态配置有关。以下是一些常见问题及解决方法,包括关闭伪静态和重新配置伪静态的方法。 常见问题点击任何链接都跳转到首页 内页访问报错解决方案 方案一:关闭伪静态进入后台管理界面登录PBootCMS后台管理系统…

好用免费的截屏工具Snipaste

Snipaste Downloads 直接在官网下载免费版的 2、如果快捷键,使用不了,重新设置下快捷键(本来我这里是F1的,我重新按下F1,变成静音就可以了)

阿里云虚拟主机的PbootCMS网站为什么不显示后台登录验证码(pbootcms后台登陆不显示验证码的原因和解决方法)

在使用PBootCMS时,如果遇到后台登录验证码不显示的问题,通常与服务器配置或PHP设置有关。以下是具体原因分析和解决方法: 原因分析输出缓冲区未开启PHP的输出缓冲区(Output Buffering)未开启,导致某些动态内容(如验证码图片)无法正常输出。权限问题文件或目录权限设置不…

八大核心能力铸就销售精英:解锁成功销售的密钥

成功销售,既是精妙绝伦的艺术展现,也是融汇多元技能的卓越实践。无论企业处于初创的萌芽阶段,还是屹立行业的巅峰之列,跨越销售高峰的征途上,销售人员所掌握的八大核心能力,如同星辰指引,不可或缺。这八大能力,如同精密齿轮,紧密咬合,共同铺设了一条通往辉煌业绩的坚…

如何使用JAVA获取淘宝商品详情?

在电子商务的世界里,淘宝作为一个庞大的在线购物平台,拥有丰富的商品信息。对于开发者来说,能够获取淘宝商品的详细信息是一项非常有用的技能。本文将介绍如何使用Java编写爬虫程序,获取淘宝商品的详细信息。 淘宝商品详情的重要性 淘宝商品详情包括商品标题、价格、销量、…

Git 与标签管理

在 Git 中,标签 tag 是指向某个 commit 的指针(所以创建和删除都很快)。在 Git 中,标签 tag 是指向某个 commit 的指针(所以创建和删除都很快)。Git 有 commit id 了,为什么还要有 tag?commit id 是一串无规律的数字,不好记;而 tag 是我们自定义的,例如我们可以命名…

华为GaussDB数据库之Yukon安装与使用

一、Yukon简介 Yukon(禹贡),基于openGauss、PostgreSQL、GaussDB数据库扩展地理空间数据的存储和管理能力,提供专业的GIS(Geographic Information System)功能,赋能传统关系型数据库。 Yukon 支持二三维一体化的空间数据存储能力:官网地址https://yukon.supermap.io/,此…