首页 > 其他分享 >9.27 代码练习,以及教你写自己的qsort函数

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

时间:2024-09-27 10:03:09浏览次数:1  
标签:9.27 int void 练习 qsort char base student sizeof

学生成绩系统代码

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;

}

标签:9.27,int,void,练习,qsort,char,base,student,sizeof
From: https://www.cnblogs.com/wxsatel/p/18435103

相关文章

  • 01 重点 导入模块练习题
    练习1:client飘红可以导入原因:因为当前运行的run.py文件,此时当前目录下面的所有文件都会自动增加到sys.path里面,此时bin目录下面的所有模块都可以导入重点。练习2:#在排除pycharm操作下,此场景下在终端运行run.py文件中,不能导入x方法。原因:s21test路径没有导入到sys.path......
  • HTML和CSS中的浮动以及边框塌陷解决方案(内置练习及答案)
    一、浮动概述在HTML和CSS中,“浮动”(Float)是一种布局技术,它允许元素脱离其正常的文档流,向左或向右移动,直到它的外边缘碰到包含框或另一个浮动元素的边缘。浮动元素仍然保持块级盒模型的特性(如可以设置宽度和高度),但是它们不再占据文档流中的空间,这意呀着文档中的其他元素会......
  • java练习生第二练
    不可变集合不可变集合(ImmutableCollections)在编程中指的是一旦创建,其内容(如元素、大小等)就不能被修改的集合类型。这类集合对于线程安全非常有用,因为它们自然避免了多线程环境下因并发修改而产生的竞争条件和错误。同时,它们也有助于设计不可变对象,这对于确保数据一致性和简......
  • 2023.9.25 近期练习
    CF1261FXor-Set我们把\(A,B\)集合分别处理,把其拥有的区间放到字典树上,就会拆成\(O(n\logV)\)个区间。考虑其两两组合,每个区间都是形如前面若干位确定,后面\(x\)位任意。两个区间组合,就是取\(x\)更大的那个后面都是任意的,前面的若干位合并起来即可。但是这样就会有\(......
  • 20240924_102514 c语言 循环练习题
    ......
  • 22 lambda 练习
    **```py练习题1USER_LIST=[]deffunc0(x):v=USER_LIST.append(x)#列表.append没有返回值v=None,insert/extend也没有返回值returnv#将None进行返回result=func0('alex')print(result)练习题2deffunc0(x):v=x.strip()#将去除空格的字符串.生成新的值......
  • 05 函数练习
    5、函数练习题#1.请写一个函数,函数计算列表info=[11,22,33,44,55]中所有元素的和。defget_sum():info=[11,22,33,44,55]data=0foritemininfo:data+=itemprint(data)get_sum()#2.请写一个函数,函数计算列表中所有元素的和。......
  • 07 函数练习二
    8、练习题2P94#1.写函数,计算一个列表中有多少个数字,打印:列表中有%s个数字。#提示:type('x')==int判断是否是数字。"""#方式一:defget_list_counter1(data_list):count=0foritemindata_list:iftype(item)==int:count+=......
  • 05 练习操作
    练习#!/usr/bin/envpython#-*-coding:utf-8-*-#########################读取:r,只读不能写+文件不存在报错##########################"""#打开文件file_object=open('log.txt',mode='r',encoding='utf-8')#r,read;w,write;......
  • 05 深浅拷贝 练习一
    """#可变-浅拷贝:拷贝第一层-深拷贝:拷贝所有数据""""""#应该每次都拷贝一份(但由于小数据池,未拷贝)v1='alex'importcopyv2=copy.copy(v1)print(id(v1),id(v2))v3=copy.deepcopy(v1)print(id(v1),id(v3))""""......