zoukankan      html  css  js  c++  java
  • 基数排序(桶排序)--静态链表实现

    原理

          基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

          基数排序的主要思路:将所有待比较数值(注意,必须是正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始, 依次进行一次稳定排序(注意必须是稳定的),这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

    实现方法

    最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。

    最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。

    LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。这里以LSD法为例。

    具体实现

    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    
    typedef struct node{              //定义结点
    	int data;                       
    	int next;                     //静态链表,空指针默认为-1
    }Node;
    
    int data[101];                    //待排序的数组   
    Node bucket[10];                  //桶数组
    Node d[101];                      //将待排序的数组构造成Node类型的数组
    int n;                            //待排序数组的数的个数
    
    int getdigit(){                   //获取数组中最多的位数
    	int max=1;
    	for(int i=0;i<n;i++){
    		int x=data[i];
    		int num=1;
    		while(x/10){
    			x/=10;
    			num++;
    		}
    		if(num>max)
    			max=num;
    	}
    	return max;
    }
    
    void init(){                      //清空桶数组和d数组
    	for(int i=0;i<10;i++){
    		bucket[i].data=i;
    		bucket[i].next=-1;
    	}
    	for(int i=0;i<n;i++){
    		d[i].data=data[i];        //将data数组中的数顺序地赋给d数组
    		d[i].next=-1;
    	}
    }
    
    void Radixsort(){
    	int digit=getdigit();         //数组中的数的位数的最大值
    	int key=1;
    	for(int i=0;i<digit;i++){     //装桶,出桶的次数
    		init();
    		for(int i=n-1;i>=0;i--){  //按从大到小的顺序装桶
    			int a=(d[i].data/key)%10;
    			d[i].next=bucket[a].next;
    			bucket[a].next=i;
    		}
    		int b=0;                  
    		for(int i=0;i<10;i++){    //对桶数组从上到下出桶到data数组中去
    			if(bucket[i].next!=-1){
    				int p=bucket[i].next;
    				data[b++]=d[p].data;
    				while(d[p].next!=-1){
    					data[b++]=d[d[p].next].data;
    					p=d[p].next;
    				}
    			}
    		}
    		key*=10;                   //key值乘以10
    	}
    }
    
    void print(){                      //输出数组
    	for(int i=0;i<n;i++)
    		printf("%d ",data[i]);
    	printf("
    ");
    }
    
    int main(){
    	printf("Please input the size of array:");
    	scanf("%d",&n);                //输入数组元素的个数
    	for(int i=0;i<n;i++)
    		scanf("%d",&data[i]);
    	Radixsort();
    	print();
    	return 0;	
    }
  • 相关阅读:
    QPS、TPS、RT、并发数、吞吐量理解和性能优化深入思考
    从开源协议到谷歌禁用华为、Docker实体清单事件
    如何画好架构图?
    使用委托的异步方法
    里氏替换原则(转)
    HTTP协议详解(转)
    httpApplication事件和asp.net生命周期(整理)
    WebDev.WebServer.exe
    正则表达式的3种匹配模式
    Code First实体与数据表之间的映射关系
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10326081.html
Copyright © 2011-2022 走看看