系统内自带的qsort与bsearch函数是经过多次优化的函数,效率极高。因此常选用这两个函数完成排序和查找工作。但qsort与bsearch只作用于连续存储单元,不能直接作用于链表。我的解决方法是将链表所有节点的地址存入一个指针数组中,对这个指针数组使用qsort与bsearch函数进行查找与排序。而查找与排序的规则是按照指针数组内指针指向的链表节点中的相应内容的大小,这个功能由qsort与bsearch调用的cmpfun_s函数定义与实现。
排序部分代码:
p为存有链表每个节点地址的指针数组(**型) n为链表节点个数 (int型)
//对指针数组排序,排序的规则是按照数组内指针指向的链表节点中的相应内容的大小qsort((void*)p,n,sizeof(p[0]),cmpfun_s);
//排序规则与对比
int cmpfun_s(const void**a,const void**b)
{
struct student *c,*d;
//调入指针数组内指针指向的链表节点地址
c=(struct student*)*a;
d=(struct student*)*b;
//比较链表节点中的相应内容的大小
return strcmp(c->num,d->num);
}
此处的cmpfun_s制定的规则是依照链表节点中num值大小进行排序,而排序的对象是元素指向节点的指针数组。qsort中引用的四个参数全部与p相关,全部针对指针数组型。查找的原理相同,只是多了一个搜索目标key其类型也为指针数组。
排序部分的技术同样应用于录取部分中
搜索部分的代码:
scanf("%s",gkey);/*得到搜索目标*/
*key=gkey;/*将搜索目标化为指针数组形式,与bsearch其他项匹配*/
//对指针数组内指针所指向的链表节点中的内容进行搜索
result=(struct student*)bsearch((void*)key,(void*)p,n,sizeof(p[0]),cmpfun_s);
qsort中引用的五个参数全部针对指针数组型。cmpfun_s函数不变。
另转:
我们先来看一下这个函数的原型:
void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );
compare( (void *) elem1, (void *) elem2 );
void *base //被排序的项目
size_t num//被排序的项目的数目
size_t width//被排序单个项目所占内存
int (__cdecl *compare )(const void *elem1, const void *elem2 ) //大小比较函数,以下表格
//函数的是返回值
返回值 描述
< 0 elem1 比 elem2 小
0 elem1 等于 elem2
> 0 elem1 比 elem2 大
一、对int类型数组排序
int num[100];
int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}
qsort(num,100,sizeof(num[0]),cmp);
示例代码:
#include<iostream.h>
#include<stdlib.h>
int compare(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
void main()
{
int num[10]={11,35,65,25,79,54,34,66,92,30};
qsort(num,10,sizeof(int),compare);
for(int i=0;i<10;i++)
cout<<num[i]<<endl;
}
二、对char类型数组排序(同int类型)
char word[100];
int cmp( const void *a , const void *b )
{
return *(char *)a - *(int *)b;
}
qsort(word,100,sizeof(word[0]),cmp);
三、对double类型数组排序(特别要注意)
double in[100];int cmp( const void *a , const void *b )
{
return *(double *)a > *(double *)b ? 1 : -1;
// 注意,直接相减不能返回整形数
}
qsort(in,100,sizeof(in[0]),cmp);
四、对结构体一级排序struct In
{
double data;
int other;
}
s[100]
//按照data的值从小到大将结构体排序,关于结构体内的排序关键数据data的类型可以很多种,参考上面的例子写
int cmp( const void *a ,const void *b)
{
return (*(In *)a)->data > (*(In *)b)->data ? 1 : -1;
}
qsort(s,100,sizeof(s[0]),cmp);
五、对结构体二级排序
struct In
{
int x;
int y;
}s[100];
//按照x从小到大排序,当x相等时按照y从大到小排序
int cmp( const void *a , const void *b )
{
struct In *c = (In *)a;
struct In *d = (In *)b;
if(c->x != d->x) return c->x - d->x;
else return d->y - c->y;
}
qsort(s,100,sizeof(s[0]),cmp);
//按照结构体中字符串str的字典顺序排序
struct In
{
int data;
char str[100];
}s[100];
int cmp ( const void *a , const void *b )
{
return strcmp( (*(In *)a)->str , (*(In *)b)->str );
}
qsort(s,100,sizeof(s[0]),cmp);
六、对字符串进行排序示例代码:
#include<iostream.h>
#include<stdlib.h>
#include<string.h>
//using namespace std;int compare(const void *a,const void *b)
{
return strcmp(*(char **)a,*(char **)b);
}
void main()
{
char *str[3]={"leebame","miyan","love"};
qsort(str,4,sizeof(str[0]),compare);
for(int i=0;i<3;i++)
cout<<str[i]<<' ';
}