排序算法

1. 桶排序

桶排序被称之为最快最简单的排序算法。顾名思义,桶排序是将所要排序的东西分装到有限数量的桶子里,然后对每个桶再分别排序,最后将各个桶中的数据有序的合并起来即可。

步骤

1.假设待排序的一组数统一的分布在一个范围中,并将这一范围划分成几个自范围,也就是桶。
2.将待排序的一组数,分挡归入这些子桶中,并将桶中的数据进行排序。
3.将各个桶中的数据有序的合并起来。

eg: 有一组数array=[29, 25, 3, 49, 9, 37, 21, 43],数组中最大数为49。

  1. 先设置5个桶,范围为:0-9,10-19,20-29,30-39,40-49,然后分别将这些数放入对应的桶中。
  2. 然后,分别对每个桶里面的数进行排序,或者再将数放入桶中时用插入排序进行排序。
    3.例子 代码

2.冒泡排序

冒泡排序解决桶排序占用空间大和一些不是整数类的问题。
思想:每次比较两个相邻元素,如果他们的顺序错误,我们就将其交换。
原理:每一趟只能确定将一个数归位。如果有 n 个数进行排序,只需将 n-1 个数归位,也就是说要进行 n-1 趟操作。而“每一趟”都需要从第 1 位开始进行相邻两个数的比较,将较小的一个数放在后面,比较完毕后向后挪一位继续比较下面两个相邻数的大小,重复此步骤,直到最后一个尚未归位的数,已经归位的数则无需再进行比较。

#include <stdio.h>
int main(){
    int a[100],i,j,t,n;
    scanf("%d",&n);//输入一个数,表示接下来有N个数
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n-1;i++){//只需n-1趟排序
        for(int j=1;j<=n-1;j++){//进行比较换位
            if(a[j]<a[j+1]){
                t=a[j];
                a[j]=a[j+1];a[j+1]=t;
            }
        }
        for (int i = 0; i < n; i+=)
        {
            printf("%d\n",a[i] );
        }
        getchar();getchar();
        return 0;
    }
}

时间复杂度非常高O(n^2);
冒泡排序的优化:.

1. 设置一个标志域flag,如果一趟排序发生变化,那么flag变为true。相反则为false,说明此序列已有序,就不必再进行比较。

int main{
    int i,j;
    bool flag=true;
    for(int i=o;i<array.length-1&&flag;i++){
        flag=false;
        for(j=1;j<array.length-1;j++){
            ifarray[j]<array[j-1]){
                swap(array[j],array[j-1]);
                flag=true;//有交换,表明当前序列尚未有序,标志为ture
        }
    }
}

2. 另一种特殊的优化算法,带有偶然性。假设有序列array={2,1,5,4,0,6,7,8,9}按升序排序,则只需对无序区{2,1,5,4,0}进行排序即可。

3.快速排序

步骤:

  1. 找到一个基数,作为我们后续比较的对象。(我以升序为主写的文档。)
  2. 先从右往左找一个小于 基数的数,称其为哨兵A,再从左往右找一个大于 基数 的数,称其为哨兵B,然后交换他们。直到,左右两个哨兵相遇,我们第一趟排序完成。
  3. 此时我们可以将一整个序列分解成两个以基数为中心的序列,继续应用2方法将其调整。直到归位。

    原理:
    快排算法之所以性能好,是因为每次都是跳跃式的交换,每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。平均复杂度O(NlogN)。

#include <stdio.h>
int a[101],n;
void quicksort(int left,int right){
    int i,j,t,temp;
    if(left>right){
        return 0;
    }

    temp=a[left];//temp中存的就是基数
    i=left;
    j=right;
    while(i!=j){
        while(a[j]>=temp&&i<j)
            j--;
        while(a[i]<temp&&i<j)
            i++;
        if(i<j){
            t=a[i];
            a[i]=a[j];
            a[j]=t;
        }
    }
    //最终将基准数归位
    a[left]=a[i];
    a[i]=temp;
    quicksort(left,i-1);//继续处理左边的,这里是一个递归的过程
    quicksort(i+1,right);//继续处理右边的 ,这里是一个递归的过程
}

int main(){
    int i,j,t;
    //读入数据
    scanf("%d",&n);
    for(i=1;i<=n;i++){
       scanf("%d",&a[i]);
    }
    quicksort(1,n); //快速排序调用

    //输出排序后的结果
    for(i=1;i<=n;i++){
    printf("%d ",a[i]);
    getchar();getchar();
    return 0;
    }
}

就先整理这三种,之后再补充。
参考原文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值