C语言: 排序
在C语言的学习之中,经常会遇见排序的问题;
对于不同的问题,排序的方法也不同;
针对排序问题,这里由简单到复杂给出几种排序的方法:
包括:
1、选择排序;
2、冒泡排序;
3、c语言中的快排 [qsort函数] (数字,字符……);
4、c++中的快排 [sort函数] (……);
1、选择排序:
方法:
每次循环挑出要排列的数字串中最大的一个数放在数组的最后,
进行n次循环;
选择排序函数:
// 参数a为需要排序的数组
// 参数n为需要排序数组的元素个数
void selectsort(int *a,int n)
{
int i,j,temp = 0,flag = 0;
for(i = 0; i < n-1; i++) // 大循环,用于控制程序不再对已经排好序的数进行操作
{
temp = a[i];
flag = i;
for(j = i+1; j < n; j++) // 小循环,用于从前往后扫描数组并选择最小数
{
if(a[j] < temp)
{
temp = a[j];
flag = j; // 目前最小的元素的下标
}
}
if(flag != i) // 如果最小的元素不是进行筛选的数据中的第一个,则将最小数据与第一个筛选数据交换
{
a[flag] = a[i];
a[i] = temp;
}
}
}
源代码:
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
// 用于对数组进行选择排序法操作
// 参数a为需要排序的数组
// 参数n为需要排序数组的元素个数
void selectsort(int *a,int n)
{
int i,j,temp = 0,flag = 0;
for(i = 0; i < n-1; i++) // 大循环,用于控制程序不再对已经排好序的数进行操作
{
temp = a[i];
flag = i;
for(j = i+1; j < n; j++) // 小循环,用于从前往后扫描数组并选择最小数
{
if(a[j] < temp)
{
temp = a[j];
flag = j; // 目前最小的元素的下标
}
}
if(flag != i) // 如果最小的元素不是进行筛选的数据中的第一个,则将最小数据与第一个筛选数据交换
{
a[flag] = a[i];
a[i] = temp;
}
}
}
int main()
{
int n,input;
scanf("%d",&n);
int *shuzu=(int*)malloc(sizeof(int)*n);
for(input=0; input<n; input++) scanf("%d",&shuzu[input]);
selectsort(shuzu,n); // 调用选择排序法
for(input = 0; input < n; input++)
printf("%d\t", shuzu[input]);
getchar();
return 0;
}
2、冒泡排序:
方法:
每次循环把最大的一个数放在最后面,循环n次,每次n-num个数;
冒泡排序源代码:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
int main()
{
int n,input,i,j,temp;
scanf("%d",&n);
int *shuzu=(int*)malloc(sizeof(int)*n);
for(input=0; input<n; input++) scanf("%d",&shuzu[input]);
for(i=0; i<n; i++)
for(j=0; j<n-i; j++)
if(shuzu[j]>shuzu[j+1])
{
temp=shuzu[j+1];
shuzu[j+1]=shuzu[j];
shuzu[j]=temp;
}
for(input=0; input<n; input++) printf("%d\t",shuzu[input]);
printf("\n");
}
3、c语言中的qsort函数:
1. 对int型的排序:
方法:
调用#include<stdlib.h>中的 qsort( a, n, sizeof(a[0]), cmp);
a : 要排列的数组名
n : 要排列数字的个数
sizeof (a[0]) : 要排列的数字的"格式”(单个数字长度)
cmp : 比较函数:
①. 从小到大排列:
int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
②. 从小到大排列:
int cmp(const void *a,const void *b)
{
return *(int *)b-*(int *)a;
}
附上源代码:
#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
int main()
{
int n,i;
int a[1010];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
qsort(a,n,sizeof(a[0]),cmp);
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
printf("\n");
return 0;
}
2. 对char型的排序:
方法:
char型其实就是特殊的int型数据,可用与int型相似的方法排序:
cmp函数:( 从小到大 )
int cmp ( const void *a , const void *b )
{
return (*(char*)a-*(char*)b);
}
附上源代码:
#include<stdio.h>
#include<stdlib.h>
int cmp ( const void *a , const void *b )
{
return (*(char*)a-*(char*)b);
}
main()
{
int n,i;
char a[1010];
scanf("%d",&n);
getchar(); // 吃掉回车
for(i=0;i<n;i++)
{
scanf("%c",&a[i]);
}
qsort(a,n,sizeof(a[0]),cmp);
for(i=0;i<n;i++)
{
printf("%c",a[i]);
}
printf("\n");
return 0;
}
3. 对double型的排序:
方法:
因为 cmp函数的返回值只能为整形,所以
cmp函数形式如下:
cmp函数:( 从小到大 )
int cmp(const void *a,const void *b)
{
if(*(double *)a>*(double *)b)
return 1;
//else
return -1;
//return *(double *)a-*(double *)b; // Wrong
}
附上源代码:
#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b)
{
if(*(double *)a>*(double *)b)
return 1;
//else
return -1;
//return *(double *)a-*(double *)b;
}
int main()
{
double a[1010];
int n,i;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%lf",&a[i]);
}
qsort(a,n,sizeof(a[0]),cmp);
for(i=0;i<n;i++)
{
printf("%lf ",a[i]);
}
printf("\n");
}
4. 对string型的排序:
方法:
因为 字符串型用strcmp函数比较,所以
cmp函数形式如下:
cmp函数:( 从小到大 )
int cmp(const void *a,const void *b)
{
return strcmp((char *)b,(char *)a);
}
附上源代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char str[100][1010]; // 最多100个字符串,每个字符串最多1010个字符
int cmp(const void *a,const void *b)
{
return strcmp((char *)b,(char *)a);
}
int main()
{
int n,i;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%s",str[i]);
}
qsort(str,n,sizeof(str[0]),cmp);
for(i=0;i<n;i++)
{
printf("%s\n",str[i]);
}
return 0;
}
5. 对结构体的排序:
方法:
结构体型的排序比较复杂
有以下几种情况:
①. 对结构体中的一个元素进行排序 :
除了要符合结构体定义,引用规范外,与单个排序基本相同:
cmp函数如下:
int cmp(const void *a,const void *b)
{
//return strcmp((*(node *)a).str,(*(node *)b).str); // 对结构体里的字符串排序
return (*(node *)a).u-(*(node *)b).u;
}
附上源代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node
{
int u,w;
double v;
char str[1010];
}b[1010];
int cmp(const void *a,const void *b)
{
//return strcmp((*(node *)a).str,(*(node *)b).str); // 对结构体里的字符串排序
return (*(node *)a).u-(*(node *)b).u;
}
int main()
{
int n,i;
scanf("%d",&n);//结构体数组个数
for(i=0;i<n;i++)
{
scanf("%d",&b[i].u);
}
qsort(b,n,sizeof(b[0]),cmp);
for(i=0;i<n;i++)
{
printf("%d\n",b[i].u);
}
}
②. 对结构体中的两个( 或以上 )元素进行排序 ( 在某个元素相同的时候,比较其他元素 ) :
通常在cmp语句中加入一个if判断语句( 在元素相同时 ),判断其他比较元素的大小:
cmp函数如下:
int cmp(const void *a,const void *b)
{
if((*(node *)a).u==(*(node *)b).u) // 在结构体 u 类型数值相同时,比较类型 w ;
return (*(node *)b).w-(*(node *)a).w;
return (*(node *)a).u-(*(node *)b).u; // 否则按 u 类型输出;
}
附上源代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node
{
int u,w;
double v;
char str[1010];
}b[1010];
int cmp(const void *a,const void *b)
{
if((*(node *)a).u==(*(node *)b).u) // 在结构体 u 类型数值相同时,比较类型 w ;
return (*(node *)b).w-(*(node *)a).w;
return (*(node *)a).u-(*(node *)b).u; // 否则按 u 类型输出;
}
int main()
{
int n,i;
scanf("%d",&n); // 结构体数组个数;
for(i=0;i<n;i++)
{
scanf("%d%d",&b[i].u,&b[i].w);
}
qsort(b,n,sizeof(b[0]),cmp);
for(i=0;i<n;i++)
{
printf("%d %d\n",b[i].u,b[i].w);
}
}
4、c++语言中的sort函数:
1. 对int型的排序:
方法:
调用c++中的#include <algorithm>头文件,中的sort( a, a+n, cmp)可实现排序功能;
a : 要排列的数组名
n : 要排列数字的个数
cmp : 比较函数( 若从小到大排列[ 默认排列方式 ] cmp 可以省略):
①. 从小到大排列:
int cmp(int a, int b)
{
return a < b;
}
②. 从大到小排列:
int cmp(int a, int b)
{
return a > b;
}
附上源代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cmp(int a, int b)
{
return a < b;
}
int main ()
{
int n;
int a[10];
scanf("%d",&n);
for(int i = 0; i < n; ++i)
scanf("%d", &a[i]);
sort(a , a + n,cmp);
for(int i = 0; i < n; ++i)
printf("%d ", a[i]);
return 0;
}
2. 对char型的排序:
方法:
与C语言相同,char型其实就是特殊的int型数据,可用与int型相似的方法排序:
cmp函数:( 从小到大 )
int cmp(char a, char b)
{
return a < b;
}
附上源代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cmp(char a, char b)
{
return a < b;
}
int main ()
{
int i,n;
char a[10];
scanf("%d", &n);
getchar();
for(i=0; i<n; i++)
scanf("%c", &a[i]);
sort(a, a + 3,cmp);
for(i=0; i<n; i++)
printf("%c\n", a[i]);
return 0;
}
3. 对double型的排序:
方法:
和C语言相同,因为 cmp函数的返回值为整形,所以
cmp函数形式如下:
cmp函数:( 从小到大 )
int cmp(double a,double b)
{
if(a<b) return 1;
return 0;
}
附上源代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cmp(double a,double b)
{
if(a<b) return 1;
return 0;
}
int main ()
{
int n;
double a[10];
scanf("%d",&n);
for(int i = 0; i < n; ++i)
scanf("%lf", &a[i]);
sort(a , a + n);
for(int i = 0; i < n; ++i)
printf("%lf ", a[i]);
return 0;
}
4. 对string型的排序:
方法:
cmp函数( 含结构体 ):( 从小到大 )
struct node
{
char a[20];
}str[20];
int cmp(node s1,node s2)
{
return strcmp(s1.a,s2.a) < 0;
}
附上源代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
char a[20];
}str[20];
int cmp(node s1,node s2)
{
return strcmp(s1.a,s2.a) < 0;
}
int main ()
{
int n,i;
scanf("%d", &n);
for(i = 0; i < n; ++i)
scanf("%s",&str[i].a);
sort(str, str + n, cmp);
for(int i = 0; i < n; ++i)
printf("%s ",str[i].a);
return 0;
}
5. 对结构体的排序:
方法:
和C语言相同,C++也有以下几种情况:
①. 对结构体中的一个元素进行排序 ( ) :
除了要符合结构体定义,引用规范外,与单个排序基本相同:
cmp函数如下:
int cmp()
{
//return strcmp((*(node *)a).str,(*(node *)b).str); // 对结构体里的字符串排序
return (*(node *)a).u-(*(node *)b).u;
}
附上源代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
int m,n;
char a[20];
}stru[20];
int cmp(node s1,node s2)
{
return s1.m<s2.m;
}
int main ()
{
int n,i;
scanf("%d", &n);
for(i = 0; i < n; ++i)
scanf("%d",&stru[i].m);
sort(stru, stru + n, cmp);
for(int i = 0; i < n; ++i)
printf("%d\n",stru[i].m);
return 0;
}
②.与C语言相同的:
对结构体中的两个( 或以上 )元素进行排序时 ( 在某个元素相同的时候,比较其他元素 ) :
通常在cmp语句中加入一个if判断语句( 在元素相同时 ),判断其他比较元素的大小:
cmp函数如下( 包括对结构体的定义 ):
struct node
{
int m,n;
char a[20];
}stru[20];
int cmp(node s1,node s2)
{
if(s1.m==s2.m) return s1.n<s2.n;
return s1.m<s2.m;
}
附上源代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
int m,n;
char a[20];
}stru[20];
int cmp(node s1,node s2)
{
if(s1.m==s2.m) return s1.n<s2.n;
return s1.m<s2.m;
}
int main ()
{
int n,i;
scanf("%d", &n);
for(i = 0; i < n; ++i)
scanf("%d%d",&stru[i].m,&stru[i].n);
sort(stru, stru + n, cmp);
for(int i = 0; i < n; ++i)
printf("%d %d\n",stru[i].m,stru[i].n);
return 0;
}
自己也需要更加努力才是……。