目录
一. 自定义排序规则
1. 常规数据类型排序
#include <stdio.h>
#include <stdlib.h>
#define EPS 1e-10
//升序排列
int cmp1(const void *a,const void *b)
{
return (*(int*)a-*(int*)b);//若返回值>0则把a排在b后面,等于0则a==b,<0则把a排在b前面。升降排序与减的顺序有关。
}
//逆序排列
int cmp2(const void *a,const void *b)
{
return (*(int*)b-*(int*)a);
}
//强制转换
int cmp3(const void *a,const void *b)
{
return (*(char*)a-*(char*)b);
}
//double类型特殊判断相等
int cmp4(const void *a,const void *b)
{
if(fabs(*(double*)a-*(double*)b)<=EPS)
return 0;
else
return (*(double*)a-*(double*)b)>0?1:-1;
}
int main()
{
int i,j;
int number[10]= {2,5,1,0,9,6,7,8,3,6};
char sign[10]="bacdefkyuo";
double uncertain[10]= {0.55,3.14,1.68,2.0003,4.00,5,9.13,7.36,4,3.33};
printf("排序前:\n");
for(i=0; i<10; i++)
printf("%d ",number[i]);
printf("\n");
for(i=0; i<10; i++)
printf("%c ",sign[i]);
printf("\n");
for(i=0; i<10; i++)
{
printf("%.2lf ",uncertain[i]);
}
printf("\n");
qsort(number,10,sizeof(number[0]),cmp1);//数组名,元素个数,单个元素大小,比较函数(大于返回1,小于返回-1,等于返回0)
qsort(sign,10,sizeof(sign[0]),cmp3);
qsort(uncertain,10,sizeof(uncertain[0]),cmp4);
printf("排序后:\n");
for(i=0; i<10; i++)
printf("%d ",number[i]);
printf("\n");
for(i=0; i<10; i++)
printf("%c ",sign[i]);
printf("\n");
for(i=0; i<10; i++)
{
printf("%.2lf ",uncertain[i]);
}
printf("\n");
printf("逆序:\n");
qsort(number,10,sizeof(number[0]),cmp2);
for(i=0; i<10; i++)
printf("%d ",number[i]);
printf("\n");
return 0;
}
2. 特殊数据类型排序
2.1 字符串字典序排序
//1.指针类型
char **p;(二位字符数组)//char *p[10]也一样
qsort(p,N,sizeof(char*),cmp);
int cmp(const void *a,const void *b)
{
return strcmp(*(char**)a,*(char**)b);
}
//2.数组类型
char s[100][100];
int cmp(constvoid *a,constvoid *b)
{
return(strcmp((char*)a,(char*)b));
}
//3.排序
qsort(s,n,sizeof(s[0]),cmp);
2.2 结构体一级排序
struct node
{
double data;int no;
} s[100];
int i,n;int cmp(constvoid *a,constvoid *b)
{
struct node *aa=(node *)a;
struct node *bb=(node *)b;
return(((aa->data)>(bb->data))?1:-1);//或者return(*(node *)a).data-(*(node *)b).data;
}
qsort(s,n,sizeof(s[0]),cmp);
2.3 结构体二级排序
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);
2.4 结构体字符串排序
struct Node
{
int data;
char str[100];
}s[100];
//按照结构体中字符串str的字典序排序
int Comp(const void*p1,const void*p2)
{
return strcmp((*(Node*)p1).str,(*(Node*)p2).str);
}
qsort(s,100,sizeof(s[0]),Comp);
二. 例题解析
1. 问题描述
Problem Description
规范序是一种对字符串比较的排序规则,其定义如下:
(1)串长小的排在前面;(2)相同串长的按照字典序排列顺序。字符串的字典序遵循如下递归定义:
(1)两串的前n-1个字符相同,第n个字符字典序小的排在前面;(2)只有两串的字符完全相同时,才有两串相等。字符的字典序即按照字母排列的顺序,即a, b, ..., z。ASCII码范围内的字符串的字典序比较可以用strcmp()函数(原型和功能见HINT)完成。
Input
第一行输入为一个整数N(N<=100),后接N行,每行一个字符串。每个字符串仅由小写字母“a”~“z”组成,长度不超过10个字符。
Output
输出为N行,按照字符串的规范序排列,规范序小的排前面。
Sample Input
10abcbcacacacaacababcdabaSample Output
cbabcbccadaaacabaabcaca
2. 题解及代码
可以看出是
结构体二级排序,其参考代码如下:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
typedef struct
{
char str[11];
int length;
}In;
int cmp(const void*a,const void*b)
{
In*aa=(In*)a;
In*bb=(In*)b;
if((aa->length)!=(bb->length))
return ((aa->length)-(bb->length));
else
return strcmp((aa->str),(bb->str));
}
int main()
{
int N;
scanf("%d",&N);
In input[101];
getchar();
int i,j;
for(i=0;i<N;i++)
{
gets(input[i].str);
input[i].length=strlen(input[i].str);
}
qsort(input,N,sizeof(input[0]),cmp);
for(i=0;i<N;i++)
printf("%s\n",input[i].str);
return 0;
}