当前位置: 首页 > news >正文

广州网站建设 粤icpseo网站优化工具

广州网站建设 粤icp,seo网站优化工具,西昌做网站,海淀区住房和城乡建设委员会网站前言:内容包括使用库函数qsort排序任意类型的数据,模拟实现qsort函数(冒泡排序的逻辑) 我们先了解qsort函数的语法:qsort函数默认按照升序排序数据 void qsort (void* base, size_t num, size_t size,int (*compar)(…

前言:内容包括使用库函数qsort排序任意类型的数据,模拟实现qsort函数(冒泡排序的逻辑)

我们先了解qsort函数的语法:qsort函数默认按照升序排序数据

void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));

qsort函数的头文件:

#include<stdlib.h>

qsort函数有4个参数:

第一个参数 void*base:指向待排序数组的第一个元素的指针

第二个参数 size_t num:待排序数组的元素个数 

第三个参数 size_t size: 待排序数组的每个元素的所占空间的大小,单位是字节

第四个参数  int (*compar)(const void*,const void*):指向一个能够比较两个元素大小的函数,即一个函数指针,此函数需要使用者自己设计

由于设计qsort函数的人不知道 未来会是谁使用qsort函数排序哪种类型的数据,故而设计void*指针,从而能够接收任意类型数据的地址

比较两个元素大小的函数的设计规则:

 int (*compar)(const void*,const void*))

此函数的返回值:

返回值意义
<0第一个元素<第二个元素
0第一个元素=第二个元素
>0第一个元素>第二个元素

 part 1:qsort函数排序整型数据

#include<stdio.h>
#include<stdlib.h>
void Print(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}
}int cmp_int(const void* p1, const void* p2)
{return *(int*)p1 - *(int*)p2; //升序//将指针p1和p2强制类型转换成int*类型,然后对其解引用//  *(int*)p2 - *(int*)p1 降序}int main()
{int arr[10] = { 5,7,3,9,1,4,6,2,8,10 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_int);Print(arr, sz);return 0;
}

由于qsort函数默认是升序排列的,若是想要降序排列,只需将p1的位置写成p2,p2的位置写成p1 

void*的指针不能直接解引用,和++,--操作,

需要将void*类型转成你需要的类型 

part 2:qsort函数排序浮点型数据

#include<stdio.h>
#include<stdlib.h>
void Print(float arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%f\n", arr[i]);}
}
int cmp_flo(const void* p1, const void* p2)
{if (*(float*)p1 - *(float*)p2 > 0.000000)//升序{return 1; // 第一个元素大于第二个元素// 降序:*(float*)p2 - *(float*)p1 > 0.000000}else if (*(float*)p1 - *(float*)p2 < 0.000000){return -1; //第一个元素小于第二个元素// 降序:*(float*)p2 - *(float*)p1 < 0.000000}else{return 0; //第一个元素等于第二个元素}
}
int main()
{float arr[] = { 1.2f,1.1f,1.8f };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_flo);Print(arr, sz);return 0;
}

降序排列需要将所有的p1写成p2,p2写成p1

part 3:qsort函数排序字符串

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int cmp_str(const void* p1, const void* p2)
{return strcmp((char*)p1, (char*)p2);//升序//降序:strcmp((char*)p2, (char*)p1)
}
int main()
{char arr[] = "ceadb";int len = strlen(arr);qsort(arr, len, sizeof(arr[0]), cmp_str);puts(arr); //结果是abcdereturn 0;
}

part 4:qsort函数排序字符串数组 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void Print(char* arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%s\n", arr[i]);}
}
int cmp_by_len(const void* p1, const void* p2)
{return strlen(*(char**)p1) - strlen(*(char**)p2);//升序//降序:strlen(*(char**)p2) - strlen(*(char**)p1)
}
int main()
{char* arr[] = { "san","yi","ling" };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_by_len);Print(arr, sz);return 0;
}

排序按照字符串的长度排序 

一级指针数据的地址需要二级指针来接收,故而需要将指针p1和p2强制转换成二级指针(char**)

part 5 qsort函数排序结构体数据 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Stu
{char name[10];int age;
};
/*int cmp_by_age(const void* p1, const void* p2)
{return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}
*/
int cmp_by_name(const void* p1, const void* p2)
{return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}
int main()
{struct Stu s[] = { {"zhangsan",30},{"lisi",15},{"wangwa",20} };int sz = sizeof(s) / sizeof(s[0]);/*qsort(s, sz, sizeof(s[0]), cmp_by_age);*/qsort(s, sz, sizeof(s[0]), cmp_by_name);return 0;
}

结构体数据类型的排序需要首先确定按照什么来排序,这里设定一个学生类型包括:名字,年龄

故而我们有两种排序规则:其一:按照名字来排序,其二:按照年龄来排序 

 part 6:运用冒泡排序思维模拟实现qsort函数

void Swap(char* buf1, char* buf2,int width)
{int i = 0;for (i = 0; i < width; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}
}void bubble_sort(void* base, size_t sz, size_t width, int(*cmp)(const void*, const void*))
{size_t i = 0;for (i = 0; i < sz - 1; i++){size_t j = 0;int flag = 1;for (j = 0; j < sz - 1 - i; j++){if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0){Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);flag = 0;}}if (flag == 1){break;}}
}

我设定模拟qsort函数功能的函数名为bubble_sort,按照升序排列数据

冒泡排序我就不详解了

base指针:指向待排序数组的第一个元素

sz:无符号数(即正数),代表待排序数据的个数

width:一个数据所占内存空间的大小,单位是字节

cmp指针:指向一个由使用者设计的能够比较两个元素大小的函数,即cmp是一个函数指针

flag:标记某一趟排序的数组是否已经有序

1 sz个数据,共需进行sz-1趟冒泡排序

2 一趟冒泡排序内部:

首先都假设此趟数据已经有序,flag=1,若是发生了交换,则将flag置为0,一趟冒泡排序结束后判断flag的值,若是flag仍为1,说明在这一趟冒泡排序中没有数据发生交换,则表明此组数据已经有序,结束循环,若是flag变成0,说明这一趟冒泡排序由数据发生交换,表明此组数据还未有序,继续下一趟冒泡排序

 a. 若是j为下标的元素>j+1为下标的元素,则需要交换

    交换:1 若是cmp函数(比较两个元素的大小)返回值>0:第一个元素大于第二个元素,交换

        2 使用char*指针,将两个元素一个字节一个字节地完成交换,这样能够交换任意类型的数据

将指向首元素的指针base强制转换成char*类型,这样一次能够跳过一个字节

可能会有疑惑为什么不降base指针转成其他类型的指针,比如int*

因为只有char*能够一次跳过一个字节,这样对于任意类型的数据都能进行操作

 要是转成int*类型的指针,一次能够跳过4个字节,不能够随意对非整型的数据进行操作

 

(char*)base + j * width, (char*)base + (j + 1) * width
base指针跳过j个大小为width字节的元素
base指针跳过(j+1)个大小为width字节的元素

可以联想普通的冒泡排序交换数组中两个数据的方法:交换arr[j], arr[j+1]

Swap函数完成两个元素每一个字节的交换

void Swap(char* buf1, char* buf2,int width)
{int i = 0;for (i = 0; i < width; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}
}

比如数字3和数字4进行交换:

若是小端存储:

03 00 00 00 04 00 00 00   

buf1指向03 buf2指向04,交换完一对字节后,分别++,指向下一对要交换的字节

对应的颜色进行交换 03和04交换……

下面是使用模拟实现qsort函数功能的函数排序整型数组:

int cmp_int(const void* p1, const void* p2)
{return *(int*)p1 - *(int*)p2;//这是升序//降序:*(int*)p2- *(int*)p1
}
// cmp_int 函数需要我们自己设计
void Print(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}
}void Swap(char* buf1, char* buf2,int width)
{int i = 0;for (i = 0; i < width; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}
}
void bubble_sort(void* base, size_t sz, size_t width, int(*cmp)(const void*, const void*))
{size_t i = 0;for (i = 0; i < sz - 1; i++){size_t j = 0;int flag = 1;for (j = 0; j < sz - 1 - i; j++){if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0){Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);flag = 0;}}if (flag == 1){break;}}
}
int main()
{int arr[10] = { 3,6,1,7,2,8,10,9,4,5 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);Print(arr, sz);return 0;
}

当然你也可以使用自己模拟实现的qsort函数去排序其他类型的数据,比较不同类型元素大小的函数在上方都有

http://www.dinnco.com/news/62715.html

相关文章:

  • 创造自己的网站网站seo报价
  • 如何安装wordpress的插件广州百度搜索排名优化
  • 品牌推广网站怎么做郑州最好的建站公司
  • 深圳网站制作厂家模板建站
  • 镇江做网站公司重庆seo入门教程
  • 免费小程序网站google付费推广
  • 公司网站非响应式模板官网seo优化找哪家做
  • 网站备案是否收费标准可以发外链的论坛有哪些
  • 网站开发语言字典徐州seo外包平台
  • 公司网站 域名 cn com上海关键词seo
  • 医院网站设计模板页面优化算法
  • 网站建设的设计思路四川seo整站优化吧
  • asp影楼网站设计怎么找专业的营销团队
  • 网站开发的项目开发宁波seo公司
  • 网站flash banner中国职业培训在线
  • 山东做网站找谁手机网站seo免费软件
  • 网站建好了怎么做淘宝客基本seo
  • 大丰建站谷歌排名算法
  • 百色网站优化短视频搜索优化
  • 企业建设网站好吗搜索引擎优化seo应用
  • 怎么开一个做网站的工作室品牌服务推广
  • 中国建设银行网站-诚聘英才seo网站优化方法
  • 代理注册公司行情上海做seo的公司
  • 电商公司做网站网站优化的方法与技巧
  • 网上赚钱的门路石家庄seo优化公司
  • 域名网站空间友链交换不限内容
  • 最火的网页游戏排行榜西安网络推广seo0515
  • 大连云建站模板登封搜索引擎优化
  • html购物网站模板怎么制作网站
  • 做ppt音乐模板下载网站建网站需要多少钱