C语言重要排序
1,冒泡排序 2,选择排序 3.桶排序。
一,冒泡排序
1、冒泡排序的思想:它重复地走访需要排序的数列,按照已经规定好的排序顺序,每一次比较相邻两个元素,如果他们的顺序错误就把他们交换过来。 直到没有再需要交换的元素,该数列就排序完成。
2、冒泡排序的算法运作(由小到大的排列顺序
有一个数组a[10],用变量i表示它的下标(i从0开始)
比较两个相邻元素a[i]和a[i+1],如果a[i]>a[i+1],就交换这两个数的位置;
重复执行第一步,直到比较到最后一对的时候(例:首次是a[8]和a[9],此 时,a[9]的值为该数组的最大值,这个值属于有序数列);
对所有元素(除了有序数列里的元素),重复执行第一步和第二步,每执行完一次,都会找到当前比较的数里最大的那个(有序数列就会增加一个);
随着参与比较的元素越来越少,最终没有任何一对元素需要比较的时候,排序完成。
传统的冒泡排序的代码:
int a[10000];
int n,i,j;
cin>>n;
for(int i=1;i<=n;i++) //外层循环:要比较的次数;
{
for(int j=1;j<=n-i;j++) //内层循环:每次比较时,要比较的元素的范围;
{
if(a[j]>a[j+1])交换的三条语句
{
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
优化1——定义一个flag,用来判断有没有进行交换,如果在某次内层循环中没有交换操作,就说明此时数组已经是有序了的,不用再进行判断,这样可以节省时间。
int flag=1;
for(int i=1;i<=n&&flag;i++)
{
flag=0;
for(int j=1;j<=n-i;j++)
{
if(a[j]>a[j+1]
){
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
flag=1;
}
}
}
二,选择排序
思想:从第一个数开始,每次和后面剩余的数进行比较,若升序,则如果后边的数比当前数字小,进行交换,和后面的所有的数比较、交换后,就会将当前的最小值放在当前的位置
输入的序列为9 3 2 5 8 4 7 6进行一次排序后将最小的数放在了第一位(a[0]与它后面的所有数进行比较,若a[0]比后面的数大,进行交换)后面的也是这个道理
附上代码
#include <stdio.h>
int main(void)
{
int a[1001];
int n,i,j,t;
scanf("%d",&n);//n为要排序的数的个数
//输入需要排序的数
for(i=0;i<n;++i)
scanf("%d",a+i);
//接下来进行排序
for(i=0;i<n-1;++i)//因为每次需要和a[i]后面的数进行比较,所以到a[n-2](倒数第2个元素)就行
{
for(j=i+1;j<n;++j)//j从i后一个开始,a[i]与a[j]进行比较
{
if(a[i]>a[j])//a[i]为当前值,若是比后面的a[j]大,进行交换
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}//每排序一次,就会将a[i](包括a[i])之后的最小值放在a[i]的位置
for(j=0;j<n;++j)
printf("%-5d",a[j]);
printf("\n\n");
}
return 0;
}
可见,线则排序的时间复杂度也为O(N²),我们无法降低它的时间复杂度,但是也可进行优化,每次选择排序,都需要进行好多次的交换,这样也比较浪费资源,我们只需要用一个变量来存储最小值的下标(升序排序),最后进行交换,也可以达到目的,这样会节省很多时间,改进后代码如下
for(i=0;i<n-1;++i)
{
int k=i;//设置一个变量存储下标
for(j=i+1;j<n;++j)//遍历a[i]后的数
{
if(a[k]>a[j])
k=j;
}//执行过后,k会存储当前最小值的下标
//进行一次交换
t=a[k];
a[k]=a[i];
a[i]=t;
}
三,桶排序
原理很简单就是利用数组下标来排序。
桶排序以下列程序进行:
1、设置一个定量的数组当作空桶子。
2、寻访序列,并且把项目一个一个放到对应的桶子去。
3、对每个不是空的桶子进行排序。
4、从不是空的桶子里把项目再放回原来的序列中。
实现代码如下:
int n,i,j=0,t;
int b[10001];
scanf("%d",&n);//输入想要排序的数的个数
memset(b,0,sizeof(b));//对b数组初始化
for(i=1; i<=n; i++)
{
scanf("%d",&t);//输入要排序的数
b[t]++;//将某个数出现的次数记录下来例如输入1,1将被存入b[1]这个数组中
}
for(i=0; i<10001; i++)//从b[0]开始输出
{
for(j=1; j<=b[i]; j++)//输出该数的个数
printf("%d ",i);
}
以上三种为常用排序;但不实用,sort排序更加简单。
sort默认从小到大排序,
int a[10000],n,i;
for(i=0;i<n;i++)
cin>>a[i];
sort(a,a+n); //数组名,数组名+排到位数的后一个数;
如果想实现降序,需要加一个函数,
bool compare(int a,int b)
{
return a>b; //降序排列,如果改为return a<b,则为升序
}
sort(a,a+n,compare);
绝对值排序
bool compare(int a, int b)
{
return abs(a) > abs(b);
}
当然cmp函数也可以写的稍微复杂点,也就是说,
按照优先级对结构体的多个成员按照某种规则排序,
//先按照w的值升序排序,如果w相等,再按照v的值升序排序
bool cmp(node a, node b)
{
if(a.w==b.w)
return a.v<b.v;
else
return a.w<b.w;
}
//或者这样写
bool cmp(node a, node b)
{
if(a.w<b.w)
return true;
if(a.w==b.w && a.v<b.v )
return true;
return false;
}