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语言刚入门的小白,以上的几种算法还只是一些基础,在编辑过程中可能会出现错误,望大家指出;
自己也需要更加努力才是……。
相关文章推荐
- C语言 static 关键字
- CSocketServer.cpp
- 用C语言操作MySQL数据库-通用版
- 为什么C++中有头文件而Java没有头文件的呢?
- 读书笔记MoreEffectiveC++(三)
- C++中WINAPI函数参数中的IN和OUT
- C/C++中static关键字详解-zz
- [leetcode-240]Search a 2D Matrix II(C语言)
- C++this 关键字
- 黑马程序员_C语言基础_指针
- C语言中如何在main函数开始前执行函数
- 用递归方式实现将一个非负整数逆序输出
- 淘气兔图片识别SDK发布,目前支持易语言,c++
- 10个经典的C语言面试基础算法及代码
- C++学习笔记之虚拟与多态
- C++ 模版类的单向循环链式线性表
- c++大数加减法的实现
- iOS 开发第一步 C语言基础之递归
- Currency System in Geraldion
- Gerald is into Art