zoukankan      html  css  js  c++  java
  • 基数排序

    基数排序(桶排序)
    基本思想:
        是将阵列分别有限数量的桶子里。每个桶子再个别排序。桶排序是鸽巢排序的一种归纳结果。当要
    被排序的数值是均匀分配的时候,桶排序使用线性时间(O(n));
    桶排序的缺点:
        1)首先是空间复杂度比较高,需要额外开销大。排序有两个数组空间开销,一个存放待排序数组,
    一个就是所谓的桶,比如待排序值是从0到m-1,那就需要m个桶,这个桶组就要至少m个空间。
        2)其次待排序的元素都要在一定范围内等等
            桶式排序是一种分配排序。分配排序的特定是不需要进行关键码的比较,单前提是要知道待排序
        序列的一些具体情况。
    MSD:
    #include<stdio.h>
    #include<stdlib.h>

    int getdigit(int x,int d)
    {
        int a[] = {1,1,10};   //因为待排序最大数据也只有两位数,所以在此只需要到十位就满足
        return ((x/a[d])%10);  //确定桶号
    }

    void PrintArr(int ar[], int n)
    {
        int i;
        for(i=0;i<n; ++i)
            printf("%d ",ar[i]);
        printf(" ");
    }
    void msdradix_sort(int arr[],int begin,int end,int d)
    {
        const int radix = 10;
        int count[radix] , i, j;
        //置空
        for(i=0; i<radix; ++i)
        {
            count[i] = 0;
        }
        //分配桶存储空间
        int *bucket = NULL;
        bucket = (int*)malloc((end-begin +1)*sizeof(int));
        if(bucket == NULL)
            printf("error! ");
        //统计各桶需要装的元素的个数
        for(i=begin; i<=end; ++i)
        {
            int dd = getdigit(arr[i],d);
            count[dd]++;
        }
        //求出桶的边界索引,count[i]值为第i个桶的右边界索引+1
        for(i=1;i<radix; ++i)
        {
            count[i] = count[i] + count[i-1];
        }
        //这里要从右向左扫描,保证排序稳定性
        for(i = end; i>=begin; --i)
        {
            j = getdigit(arr[i],d);//求出关键码的第d位的数字, 例如:576的第3位是5
            bucket[count[j]-1] = arr[i];//放入对应的桶中,count[j]-1是第j个桶的右边界索引
            --count[j];//第j个桶放下一个元素的位置(右边界索引+1)
        }
        //注意:此时count[i]为第i个桶左边界
        //从各个桶中收集数据
        for(i = begin,j=0;i<=end; ++i,++j)
        {
            arr[i] = bucket[j];
        }
        //释放存储空间
        free(bucket);
        bucket = NULL;
        //堆各桶中数据进行再排序
        for(i=0;i<radix; i++)
        {
            int p1 = begin + count[i];     //第i个桶的左边界
            int p2 = begin + count[i+1] -1; //第i个桶的右边界
            if(p1<p2 && d > 1)
            {
                msdradix_sort(arr,p1,p2,d-1); //对第i个桶递归调用,进行基数排序,数位降1
            }
        }
    }
    int main()
    {
        int ar[] = {12,14,54,5,6,3,9,8,47,89};
        int len = sizeof(ar)/sizeof(int);
        printf("sort befor: ");
        PrintArr(ar,len);
        msdradix_sort(ar,0,len-1,2);
        printf("sort after : ");
        PrintArr(ar,len);
        return 0;
    }
    LSD:
    #include<stdio.h>
    #include<stdlib.h>

    #define MAXSIZE 10000

    int getdigit(int x,int d)
    {
        int a[] = {1,1,10,100};//最大三位数,所以这里只要百位就满足了
        return (x/a[d])%10;
    }
    void PrintArr(int ar[],int n)
    {
        int i;
        for(i =0;i<n; ++i)
        {
            printf("%d ",ar[i]);
        }
        printf(" ");
    }

    void lsdradix_sort(int arr[],int begin,int end,int d)
    {
        const int radix = 10;
        int count[radix],i,j;
        int *bucket = (int*)malloc((end - begin+1)*sizeof(int));//所有桶的空间开辟
        int k;
        //按照分配标准依次进行排序过程
        for(k=1;k<=d; ++k)
        {
            //置空
            for(i=0; i<radix; i++)
            {
                count[i] = 0;
            }
            //统计各个桶中所有数据个数
            for(i=begin; i<=end; i++)
            {
                count[getdigit(arr[i],k)]++;
            }
            //count[i]表示第i个桶的右边界索引
            for(i=1; i<radix; i++)
            {
                count[i] = count[i] + count[i-1];
            }
            //把数据依次装入桶(注意装入时候的分配技巧)
            for(i = end; i>=begin; --i) //这里要从右向左扫描,保证排序稳定性
            {
                j = getdigit(arr[i],k);//求出关键码的第k位的数字,例如:576的第3位是5
                bucket[count[j]-1] = arr[i];//放入对应的桶中,count[j]-1是j个桶的右边界索引
                --count[j];//对应桶的装入数据索引减一
            }
            //注意:此时 count[i]为i个桶左边界
            // 从各个桶中收集数据
            for(i= begin,j=0;i<=end;++i,++j)
            {
                arr[i] = bucket[j];
            }
        }
        free(bucket);
        bucket = NULL;
    }
    int main()
    {
        int br[10] = {20,80,90,589,998,985,852,123,456,789};
        printf("sort befor: ");
        PrintArr(br,10);
        lsdradix_sort(br,0,9,3);
        printf("sort after: ");
        PrintArr(br,10);
        return 0;
    }

    The future's not set,there is no fate but what we make for ourselves.
  • 相关阅读:
    caffe_实战之两个简单的例子(物体分类和人脸检测)
    《Caffe下跑AlxNet之数据处理过程》
    git使用小结
    说好的博客
    C++入门学习
    第一篇 一步一步看透C++
    第一百六十三节,jQuery,基础核心
    第一百六十二节,jQuery入门介绍
    第一百六十一节,封装库--JavaScript,完整封装库文件
    第一百六十节,封装库--JavaScript,ajax注册表单到数据库
  • 原文地址:https://www.cnblogs.com/wang1994/p/9115427.html
Copyright © 2011-2022 走看看