zoukankan      html  css  js  c++  java
  • 36排序算法之基数排序

    排序算法之基数排序

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

    原理:用整理扑克牌的例子说明基本原理。

    示例

    (1)整数排序

    将整数(元素)看成多元组(数字串)

    每个分量(一位)有m(10)种不同的取值(0,1,2,3,…)

    编号为0,1,2,…,m-1元素的有序次序===多元组的“字典次序”。

    (2)字符串排序

    例如,将英文单词排成字典次序:

    for  end  else  goto  file  int  new  case  char  and

    长度不足4个字母的单词尾部加空格符 □。

     

    算法的实现:

    (1)选用的数据结构

    1)数据采用链式存储,总队列queue

    2)结点值域为数组a[k],每个分量a[j]满足

        0≤a[j]的序号值≤m-1(j=0,2,…,k-1)

    3)m个分队列用于分组q[0],q[1],q[2],…,q[m-1]。

    (2)算法描述

    步骤1)置分量下标j等于k-1

    步骤2)[分组]

    ①将各分队列q[0],q[1],q[2],…,q[m-1]置空。

    ②依次从总队列中取下元素a,设其第j个分量a[j]的序号值为t,将该元素放在分队列q[t]的尾部,反复如此,直到把总队列中元素取完。

    步骤3)[收集]按分队列的序号由小到大,依次将分队列q[0],q[1],q[2],…,q[m-1]首尾相接,组成新的总队列。

    步骤4)j=j-1,若j<0,排序结束;否则,转步骤2。

    基数排序实现算法:

    (1)类型定义

    typedef  struct  node  //定义结点类型

      { char  a[k];       //值域和分量类型

        struct  node  *next; // 链域

      } *ptr;     // 指针类型名

    (2)实现程序

    void radix_sort(ptr &h,int k)

       {

     int i,j,y;

     char x;    

    ptr p;

         struct  {ptr head,tail;}  q[m];

     for(j=k-1;j>=0;j- -)

         { 

     for(i=0;i<m;i++)

     q[i].head=NULL;

        while(h)

           {

      x=h->a[j]; 

            y=value(x);   //将x换算成序号值

            if(q[y].head==NULL)

    q[y].head=h; 

           else

     q[y].tail->next=h;

                     q[y].tail=h;

    h=h->next;//取总队列下一个元素

           }  //分组完毕

             i=0;

       while(q[i].head==NULL)

     i++; 

       h=q[i].head;

       p=q[i].tail;  

       for(i++;i<m;i++)

          if(q[i].head)

    p->next=q[i].head,p=q[i].tail;

       p->next=NULL;

          }

       }

    源代码:
    #include<math.h>
    testBS()
    {
        inta[] = {2, 343, 342, 1, 123, 43, 4343, 433, 687, 654, 3};
        int *a_p = a;
        //计算数组长度
        intsize = sizeof(a) / sizeof(int);
        //基数排序
        bucketSort3(a_p, size);
        //打印排序后结果
        inti;
        for(i = 0; i < size; i++)
        {
            printf("%d
    ", a[i]);
        }
        intt;
        scanf("%d", t);
    }
    //基数排序
    voidbucketSort3(int *p, intn)
    {
        //获取数组中的最大数
        intmaxNum = findMaxNum(p, n);
        //获取最大数的位数,次数也是再分配的次数。
        intloopTimes = getLoopTimes(maxNum);
        inti;
        //对每一位进行桶分配
        for(i = 1; i <= loopTimes; i++)
        {
            sort2(p, n, i);
        }
    }
    //获取数字的位数
    intgetLoopTimes(intnum)
    {
        intcount = 1;
        inttemp = num / 10;
        while(temp != 0)
        {
            count++;
            temp = temp / 10;
        }
        returncount;
    }
    //查询数组中的最大数
    intfindMaxNum(int *p, intn)
    {
        inti;
        intmax = 0;
        for(i = 0; i < n; i++)
        {
            if(*(p + i) > max)
            {
                max = *(p + i);
            }
        }
        returnmax;
    }
    //将数字分配到各自的桶中,然后按照桶的顺序输出排序结果
    voidsort2(int *p, intn, intloop)
    {
        //建立一组桶此处的20是预设的根据实际数情况修改
        intbuckets[10][20] = {};
        //求桶的index的除数
        //如798个位桶index=(798/1)%10=8
        //十位桶index=(798/10)%10=9
        //百位桶index=(798/100)%10=7
        //tempNum为上式中的1、10、100
        inttempNum = (int)pow(10, loop - 1);
        inti, j;
        for(i = 0; i < n; i++)
        {
            introw_index = (*(p + i) / tempNum) % 10;
            for(j = 0; j < 20; j++)
            {
                if(buckets[row_index][j] == NULL)
                {
                    buckets[row_index][j] = *(p + i);
                    break;
                }
            }
        }
        //将桶中的数,倒回到原有数组中
        intk = 0;
        for(i = 0; i < 10; i++)
        {
            for(j = 0; j < 20; j++)
            {
                if(buckets[i][j] != NULL)
                {
                    *(p + k) = buckets[i][j];
                    buckets[i][j] = NULL;
                    k++;
                }
            }
        }
    }

  • 相关阅读:
    基于 Token 的身份验证
    学以致用二---配置Centos7.2 基本环境
    学以致用一 安装centos7.2虚拟机
    #!/usr/bin/env python与#!/usr/bin/python的区别
    centos7.2下安装python3.6.2
    Day1-python基础-变量常量
    Day1-python基础
    学python之路前的一些话
    Mybatis generator自动生成mybatis配置和类信息
    MyBatis Generator generatorConfig.xml配置详解
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/8509936.html
Copyright © 2011-2022 走看看