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

    基数排序

    • 对一组数组按个位、十位、百位、...、最高位上的数字对这组数组进行排序。

    算法流程

    • 获取所要排序的数组中最大的元素,方便提取出最大的位数
    int get_max(int a[],int n)
    {
         int maxn = a[0];
         for(int i=1;i<n;i++)
             maxn = max(maxn,a[i]);
         return max;
    }
    
    • 然后获取后,就可以依次从低位到高位向数组进行一次次的处理

      • 设exp为指数,代表当前要处理的位数,比如位数为1,exp=1;位数为2,exp=10;

      • 只要max/exp>0,就代表exp仍未达到数字的顶端

      for(exp=1;max/exp>0;exp*=10){
          CountSort(a,n,exp);
      }
      
    • 单个位置上的排序CountSort(int a[],int n,int exp)

      • 材料:

        • 桶排序:bucket[idx]表示的是idx在这个数组中有多少个

          桶排序改装:bucket[idx]表示的是以idx(0...9)在exp位有多少个

        • 前缀和:目的通过前缀和的处理将每个数字给区分开,也可以看成是把exp位上相同的数字的这一类数字锁在一定的区间,或者也可以看成赋予一定的权值给了这一类数字从而使得这一类数字与其他数字区分开来,并且通过同类的数字可以通过自己内部的减一操作来使得自己内部的数字也具有区分度。

          注意点,由于前缀和的关系,output如果不对其数组的下标进行减一的话,傻傻直接拿来用的话,是会和a的数组对不上的。

          for(int i=1;i<10;i++)
              bucket[i]+=bucket[i-1];
          
        • output数组:用来储存数组,并最终对a进行覆盖。

          output[bucket[a[i]/exp%10]] = a[i];
          
        • 同类的数字获取区分度

          bucket[a[i]/exp%10]--;
          
    • 在较低位置获取比较靠前的位置(相比于其他数字,会比较小),在较高位置的排序中也会优先被排序(这就保证了在高位上的相同数字的数字的大小的准确性)。

      比如(213,212在经过个位数的排序后会先变成212,213,然后在十位上的排序,212相对于213会获得较先被排序的机会)

    #include<bits/stdc++.h>
    using namespace std;
    int get_max(int a[],int alen)
    {
    	int maxn = a[0];
    	for(int i=1;i<alen;i++)
    	    maxn = max(maxn,a[i]);
    	return maxn;
    }
    
    void count_sort(int a[],int alen,int exp)
    {
    	int bucket[10],output[alen];
    	memset(bucket,0,sizeof(bucket));
        for(int i=0;i<alen;i++)
        {   
        	bucket[a[i]/exp%10]++;
    	}
        	
        
        for(int i=1;i<10;i++)
            bucket[i]+=bucket[i-1];
            
        for(int i=alen-1;i>=0;i--)//反着来 
        {
        	output[bucket[a[i]/exp%10]-1]=a[i];//这里有个减一,要使得output数组最终和buckets数组对上
        
    	    bucket[a[i]/exp%10]--;
    	}
    	
    	for(int i=0;i<alen;i++)
    		a[i] = output[i];
    }
    
    void radix_sort(int a[],int alen)
    {
    	int exp;
    	int maxn = get_max(a,alen);
    
    	for(exp=1;maxn/exp>0;exp*=10)
    		count_sort(a,alen,exp);
    }
    
    int main()
    {
    	int a[] = {53, 3, 542, 748, 14, 214, 154, 63, 616};
    	int alen = sizeof(a)/sizeof(a[0]);
    	
    	puts("radix_sort前");
    	for(int i=0;i<alen;i++)
    	    cout<<a[i]<<" ";
    	cout<<endl;
    	    
    	radix_sort(a,alen);
    	
    	puts("radix_sort后");
    	for(int i=0;i<alen;i++)
    	    cout<<a[i]<<" ";
        cout<<endl;
    	
    	return 0;	
    }
    
    

    其他

    获取数组长度

    int ilen = (sizeof(a)/sizeof(a[0]));
    

    参考

    基数排序

  • 相关阅读:
    vue form dynamic validator All In one
    TypeScript api response interface All In One
    closable VS closeable All In One
    macOS 如何开启 WiFi 热点 All In One
    vue css inline style All In One
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (下)
    牛腩新闻 59 整合添加新闻页 FreeTextBox 富文本编辑器,检测到有潜在危险的 Request.Form 值,DropDownList 的使用
    牛腩新闻 61尾声: error.aspx的使用 防止报错
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (上)
    牛腩新闻 62:尾声续2 asp.net的编译和发布
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/15105109.html
Copyright © 2011-2022 走看看