C语言重要排序

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

猜你喜欢

转载自blog.csdn.net/qq_43627087/article/details/85083534