hello,大家好呀!我是吴呜呜,一个新人up主。这是我的第一篇博客,希望大家能多多支持呀!现在关注了以后就是老粉喽!话不多说,我们直接来切入主题。
首先大家需要知道排序的基本方法,我再给大家稍稍介绍一下。
1.冒泡排序
话不多说,上代码。
大家看啊,我是使用了一个自己编的冒泡排序函数。冒泡排序的原理我就不介绍了,大家可以自行网上搜索,多的是。我要说的是这个函数只能排序int数组类型的值,对于初学者来说确实挺好用的。但是说实话光会这个真的不太够用。
#include<stdio.h>
void maopao(int arr[],int sz)//冒泡排序
{
//冒泡排序的趟数
int i=0;
for(i=0;i<sz-1;i++)
{
//每一趟冒泡排序
// 假设这一趟要排序的数据已经有序
for(int j=0;j<sz-1-i;j++)
{
if(arr[j]>arr[j+1])//把大于改成小于就变成降序了
{
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
//排序数据不完全有序
}
}
}
}
int main()
{
int arr[]={38,22,15,2,3,4,5,17,29,50};
int sz=sizeof(arr)/sizeof(arr[0]);
maopao(arr,sz);
for(int i=0;i<sz;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
2.万能排序
我给大家介绍一下我的万能排序法。先上代码,然后我分别给大家解释。我比较喜欢利用函数,所以我还是利用函数的形式给大家呈现的。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//void qsort (void* base, size_t num, size_t size,
//int (*compar)(const void* e1, const void* e2))//sqot函数是来比较大小的,使用时引用头文件<stdlib.h>
//base,num,size,compar,分别代表数组中第一个对象的地址,数组中元素数,数组中每个元素的字节大小,
//最后一个代表指向比较两个元素的函数的指针。
//这个函数被反复调用qsort比较两个元素。它应遵循以下原型:
//int compar(const void* e1, const void* e2);
struct stu
{
char name[50];
int age[30];
};
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;//e1减e2是升序,e2减去e1为降序
}
void test1()//int类型排序
{
int arr[] = { 1,2,4,3,6,5,9,8,7,10,25,33 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int cmp_float(const void* e1, const void* e2)
{
return ((int)(*(float*)e1 - *(float*)e2));//float函数类型不符合所以转换为int类型,e1减e2是升序,e2减去e1为降序
}
void test2()//浮点型排序
{
float f[] = { 9.0,8.0,7.0,6.0,11.0,78.0 };
int sz = sizeof(f) / sizeof(f[0]);
qsort(f, sz, sizeof(f[0]), cmp_float);
for (int j = 0; j < sz; j++)
{
printf("%f ", f[j]);
}
}
int cmp_stu_age(const void* e1, const void* e2)//结构体中的数字排序
{
stu*pa1=(stu*)e1;
stu*pa2=(stu*)e2;
return ((struct stu*)e1)->age - ((struct stu*)e2)->age;//->表示指向结构体中的age
}
void test3()//结构体中的数字排序
{
struct stu s[3] = { {"zhangsan",3},{"lisi",2},{"wangwu",1} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_age);
for (int i = 0; i < sz; i++)
{
printf("%d\n",s[i].age);
}
}
int cmp_stu_name(const void* e1, const void* e2)//结构体中的字符串排序
{
//比较字符串不能直接比较需要用strcmp函数,且引用头文件<string.h>
return strcmp(((struct stu*)e1)->name,((struct stu*)e2)->name);//->表示指向结构体中的name
}
void test4()//结构体中字符串排序
{
stu s[3] = { {"zhangsan",33},{"lisi",28},{"wangwu",56} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_name);
for (int i = 0; i < sz; i++)
{
printf("%s\n", s[i].name);//
}
}
int cmp_char(const void* e1, const void* e2)
{
return strcmp((char*)e1,(char*)e2);
}
void test5()//普通字符串排序
{
char b[][20] = { "huhu","wcs","scz","pdq" };
int sz = sizeof(b) / sizeof(b[0]);
qsort(b, sz, sizeof(b[0]), cmp_char);
for (int i = 0; i < sz; i++)
{
puts(b[i]);
}
}
int main()
{
test3();
}
代码看起来很冗长是吧!听我细细给大家分析。首先我说一下这个万能排序可以排序的内容哈。可以排序int数组类型,char数组类型,double和float数组类型,结构体中按照字典序排序类型,结构体中排序int类型,结构体中排序char,float,double类型。
如果要理解这个代码,首先我要给大家解释一下去qsort函数和compar函数。对于qsort函数
大家来看哈
void qsort (void* base, size_t num, size_t size,
int (*compar)(const void* e1,const void* e2));
从base到两个cost void* e1,void* e2分别表示为数组第一个对象的地址,数组中元素个数,数组中每个元素字节的大小,然后最后这个int (*compar)(const void* e1,const void* e2)
它是函数compar的返回值,相当于去qsort函数里面又套了一个函数,有点难理解哈。没关系,咱慢慢来哈,咱来看下面一段代码,这是我从上面一串代码中抽离出来的。
整形数组排序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;//e1减e2是升序,e2减去e1为降序
}
void test1()//int类型排序
{
int arr[] = { 1,2,4,3,6,5,9,8,7,10,25,33 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
咱看这个qsort(arr, sz, sizeof(arr[0]), cmp_int);arr对应base,数组首元素地址,sz表示数组中元素数,sizeof(arr[0])表示数组中每个元素字节大小,然后后面的cmp_int对应上面的函数int cmp_int (const void* e1, const void* e2)大家看const void*e1,const void*e2,分别就对于qsort函数的最后的那两个无返回类型的指针,然后cmp_int 函数接收了整形数组,因为e1,e2分别表示整形数组中两个元素,但是函数cmp_int接收的是指针,所以把e1转换为(int*)*e1(整形指针),再解引用加上*变成*(int*)e1,然后将二者相减,为升序。反过来是降序。我把结果给大家附上。
这是整形数组的排序。使用时只需要把我上面的一段代码复制粘贴上面,然后直接在主函数引用test1()就行。
浮点型数组排序
int cmp_float(const void* e1, const void* e2)
{
return ((int)(*(float*)e1 - *(float*)e2));//float函数类型不符合所以转换为int类型,e1减e2是升序,e2减去e1为降序
}
void test2()//浮点型排序
{
float f[] = { 9.0,8.0,7.0,6.0,11.0,78.0 };
int sz = sizeof(f) / sizeof(f[0]);
qsort(f, sz, sizeof(f[0]), cmp_float);
for (int j = 0; j < sz; j++)
{
printf("%f ", f[j]);
}
}
头文件还是要引用的,不过我省略了,test2()函数大同小异与第一个。我还是讲的是cmp_float因为是float类型的指针嘛,所以先转化为(float*)e1与(float*)e2,然后再解引用嘛就是加个*,然后二者的差再转化为int类型,如果升序还是我上面写的那个,降序的话换一下就行。老规矩,给各位看官老爷们看看结果。
字符串排序
int cmp_char(const void* e1, const void* e2)
{
return strcmp((char*)e1,(char*)e2);
}
void test3()//普通字符串排序
{
char b[][20] = { "huhu","wcs","scz","pdq" };
int sz = sizeof(b) / sizeof(b[0]);
qsort(b, sz, sizeof(b[0]), cmp_char);
for (int i = 0; i < sz; i++)
{
puts(b[i]);
}
}
这里需要给大家说明的是字符串排序是要用到strcmp函数的,具体关于strcmp函数的用法我不再赘述了,这里给大家附上链接官方的解释strcmp - C++ Reference然后打家需要注意的是下面我偷懒使用puts函数了,建议初学者还是使用print函数哈。然后上面注意不需要解引用了但还是需要转换为char指针哈。不解引用的原因是因为使用了strcmp函数。然后不需要进行相减,二者之间是逗号。然后我建议大家还是当成一个函数来用,使用的时候直接再main函数引用就行。看起来也没有那么嘈杂。当然这个也是字典序排序。继续上图
结构体中的整形数组排序
struct stu
{
char name[50];
int age[30];
};
int cmp_stu_age(const void* e1, const void* e2)//结构体中的数字排序
{
return ((struct stu*)e1)->age - ((struct stu*)e2)->age;//->表示指向结构体中的age
}
void test3()//结构体中的数字排序
{
struct stu s[3] = { {"zhangsan",3},{"lisi",2},{"wangwu",1} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_age);
for (int i = 0; i < sz; i++)
{
printf("%d\n",s[i].age);
}
}
我给大家解释一下首先还是老规矩转换为结构体指针(strcut stu*)e1,因为咱用啥就转换为啥类型的指针,然后这个->表示指向于结构体中的age,所以嘛。继续给大家。我就不上效果了,跟前面大同小异啦!
结构体中的字符数组排序
struct stu
{
char name[50];
int age[30];
};
int cmp_stu_name(const void* e1, const void* e2)//结构体中的字符串排序
{
//比较字符串不能直接比较需要用strcmp函数,且引用头文件<string.h>
return strcmp(((struct stu*)e1)->name,((struct stu*)e2)->name);//->表示指向结构体中的name
}
void test4()//结构体中字符串排序
{
stu s[3] = { {"zhangsan",33},{"lisi",28},{"wangwu",56} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_name);
for (int i = 0; i < sz; i++)
{
printf("%s\n", s[i].name);//
}
}
这个跟结构体中整形数组排序不同的是,多了个strcmp函数然后减号变成了逗号,大家使用的时候注意括号比较多,不要写错了,然后指向的话变成了->name。大家可以自己试一下。
好了,以上就是全部内容。由于本人是第一次写,难免会有写的不好的,如果写的有错误欢迎各位指正,然后自己以后也会继续更新关于C语言和前端的学习内容。希望大家可以多多支持。谢谢啦!最后,我是吴呜呜,期待下次与各位相见!