您的位置:首页 > 编程语言 > C语言/C++

Num 7 : C语言中的各种排序方法

2015-07-23 10:52 1146 查看

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型的排序:

方法:

C++中的字符串需要在结构体的条件下进行排序( C++下对结构体数组排序的一种特殊情况 ):

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;
}


作为C语言刚入门的小白,以上的几种算法还只是一些基础,在编辑过程中可能会出现错误,望大家指出;
自己也需要更加努力才是……。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: