进阶冒泡排序

qsort函数

1.认识qsort函数:

使用快速排序的思想实现的一个排序函数(默认升序)

//需要的头文件
#include <stdlib.h>
//函数使用的方法
void qsort(void* base,size_t num,size_t width,int(*cmp)(const void* e1,const void* e2));

//1.void* base:指要排序数据的起始位置,即所传递过去的数组的起始位置,即数组名
2.num:指待排序的数据元素个数
3.width:指待排序的数据的元素的个数(单位是字节),即sizeof(数组名[0])
4.int (*cmp)(const void* e1,const void* e2):这是一个函数指针,即比较函数

//初版的冒泡排序只可以排序整型数据,而qsort可以排序任意类型的数据

2.函数使用特别注意事项

int main()
{
int a=10;
void* pv=&a;
return 0;
}

//void*是无具体类型的指针;
可以接受任意类型的地址,又因为是无具体类型的指针,所以不能解引用操作,也不能+-整数;
故如若需要引用void*里面的内容,需要先转换它的类型,在进行解引用的操作

3.举例

//比较两个整型元素
//e1指向一个整数
//e2指向另外一个整数
//(注意:不能直接解引用e1,e2)
#include <stdio.h>
#include <stdlib.h>
void cmp_int(const void* e1,const void* e2)
{
return (*(int*)e1-*(int*)e2);//强制转换为int*类型后再解引用;e1>e2(>0),e1<e2(<0),e1=e2(=0);
}
int main()
{
int arr[]={9,8,7,6,5,4,3,2,1,0};
int i=0;
int sz=0;
sz=sizeof(arr)/sizeof(arr[0]);
qsort(arr,sz,sizeof(arr[0]),cmp_int);//默认为升序
for(i=0;i<sz;i++)
{
printf("%2d",arr[i]);
}
return 0;
}


//若要改成降序排列仅需要改变返回的代码
void cmp_int(const void* e1,const void* e2)
{
return (*(int*)e2-*(int*)e1);
}
//测试使用qsort函数来排序结构体
//按名字来排序//(字符窜的比较要用strcmp函数,且头文件为string.h)
#include <stdio.h>
#include <string.h>
struct Stu
{
char name[20];
int age;
};
int cmp_stu_by_name(const void* e1,const void* e2)
{
return strcmp(((struct Stu*)e1)->name,((struct Stu*)e2)->name);//结构体指针变量->成员名
}
void test1()
{
struct Stu s[]={{"zhangsan",15},{"wangwu",30},{"lisi",25}};
int i=0;
int sz=0;
sz=sizeof(s)/sizeof(s[0]);
qsort(s,sz,sizeof(s[0]),cmp_stu_by_name);
for(i=0;i<sz;i++)
{
printf("%s %d\n",s[i].name,s[i].age);
}
int main()
{
test1();
return 0;
}

//若要按照年龄排序,只需把name改成age

改造冒泡排序

1.(int*)类型的指针+1跳过4个字节

(char*)类型的指针+1跳过1个字节

base:(数组的宽度width(整型为4个字节))

444......

2.交换两个元素,不仅要知道起始位置,还要知道宽度(有几个字节就交换几对)

//升序
#include <stdio.h>
void cmp(const void* e1,const void* e2)//函数指针-比较函数
{
return (*(char*)e1-*(char*)e2);
}
void Swap(char* buf1,char* buf2,int width)//交换函数,(char*)类型+-跳过1个字节
{
int i=0;
for(i=0;i<width;i++)//若为int类型,width=4;
{
char tmp=*buf1;
*buf1=*buf2;
*buf2=tmp;
buf1++;
buf2++;
}
}
void bubble_sort(void* base,int sz,int width,int(*cmp)(const void* e1,const void* e2))
{
int i=0;
for(i=0;i<sz-1;i++)
{
int flag=1;
int j=0;
for(j=0;j<sz-1-i;j++)
{
if(cmp((char*)base+j*width,(char*)base+(j+1)*width)>0)//cmp两个参数是待比较的两个函数的地址
{
Swap((char*)base+j*width,(char*)base+(j+1)*width,width)
flag=0;
}
}
if(flag==1)
{
break;
}
}
}
int main()//主函数
{
int s[]={9,8,7,6,5,4,3,2,1,0};
int sz=0;
int i=0;
sz=sizeof(s)/sizeof(s[0]);
bubble_sort(s,sz,sizeof(s[0]),cmp);
for(i=0;i<sz;i++)
{
printf("%2d",s[i]);
}
return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值