zoukankan      html  css  js  c++  java
  • 基本排序算法之2——基数排序radixsort

      基数排序是基于桶式排序的变种,主要是为了通过多次遍历减少空间占用(效果相当显著)。其思路可以描述为:

        1.首先待排序的序列要满足基数排序的特征,比如有“基数”的概念(整数和字符串都可以套用)

        2.建立一个大小为“基数”的数组,数组每个元素是一个队列(为了节省空间应该使用链表实现)

        3.根据序列的“位数”决定遍历的次数m,每次遍历相当于按某一位做桶式排序。重复的元素push到队列中。

        4.m次遍历后排序完成,最后一次遍历输出结果。因为数据不是按线性结构存储。

      下面是我的实现,采用vector<list>结构:

     1 #include<iostream>
     2 #include<list>
     3 #include<vector>
     4 
     5 using namespace std;
     6 
     7 /*
     8  * N is the input intergers
     9  * B is base
    10  * W is the intergers's max width
    11  */
    12 void buildvector(vector<list<int> >&arr,int B)
    13 {
    14     int cnt;
    15     int num;
    16     cout<<"input count of numbers to be sorted"<<endl;
    17     cin>>cnt;
    18     for(int i=0;i<cnt;++i)
    19     {
    20         cout<<"input num["<<i+1<<"]:";
    21         cin>>num;
    22         arr[num%B].push_back(num);
    23     }
    24 }
    25 void radixsort(vector<list<int> >&arr,int B,int W)
    26 {
    27     vector<list<int> > brr(B);
    28     for(int k=2;k<=W;++k)
    29     {
    30         int BS=B;
    31         for(int j=2;j<k;++j) BS*=B;
    32         for(int i=0;i<B;++i)
    33         {
    34             while(!arr[i].empty())
    35             {
    36                 int x=arr[i].front();
    37                 brr[x/BS%B].push_back(x);
    38                 arr[i].pop_front();
    39             }
    40         }
    41         swap(arr,brr);
    42     }
    43 }
    44 void show(vector<list<int> >&arr)
    45 {
    46     vector<list<int> >::iterator itv=arr.begin();
    47     while(itv!=arr.end())
    48     {
    49         list<int>::iterator it=itv->begin();
    50         while(it!=itv->end())
    51         {
    52             cout<<*it<<' ';
    53             ++it;
    54         }
    55         ++itv;
    56     }
    57     cout<<endl;
    58 }
    59 
    60 int main()
    61 {
    62     vector<list<int> > arr(16);
    63     buildvector(arr,16);
    64     radixsort(arr,16,3);
    65     show(arr);
    66 }

      注意几点:

        1.每次遍历之后实际上要借助原始数组输出,以便下次遍历可以直接递归。我这里偷懒用了个swap操作。

        2.时间复杂度=(O(N)+O(基数))*O(位数)

        3.也可以不借助链表,仅用数组实现。每次遍历前预处理序列,找到遍历的时候每一位将会重复的元素个数,计算出该位在数组中的起始下标即可。

  • 相关阅读:
    eclipse 异常Unhandled event loop exception
    eclipse序列化生成serialVersionUID
    [转载]给10万pv的WordPress选择最便宜高可用的硬件以及WordPress高并发支持
    struts2日常
    JQuery表格展开与内容筛选
    记一次简单的清理挖矿程序过程
    【原创总结】服务为什么会报404?
    【原创总结】Tomcat进程为什么起不来?
    【原创总结】服务为什么会报500的错误?
    【原创】关于nginx.pid丢失的解决办法
  • 原文地址:https://www.cnblogs.com/jwk000/p/3116795.html
Copyright © 2011-2022 走看看