数据结构:基数排序(Radix Sort)

基数排序的概念:

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


算法描述:

  • 取得数组中的最大数,并取得位数;
  • arr为原始数组,从最低位开始取每个位组成radix数组;
  • 对radix进行计数排序(利用计数排序适用于小范围数的特点);

动态图演示:

 


算法分析:

最佳情况:T(n) = O(n * k)  

最差情况:T(n) = O(n * k)  

平均情况:T(n) = O(n * k)


代码实现:

低位优先:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <vld.h>

typedef struct Node
{
  int data;
  struct Node *next;
}Node;

typedef struct HNode
{
  struct Node* front;
  struct Node* rear;
}Node*PQueue;

//队列初始化
void lnitQueue(PQueue pq)
{
   assert(pq != NULL);

   pq->front = NULL;
   pq->rear = NULL;
}

static Node *BuyNode(int val)
{
   //创建结点
   Node* p = (Node*)malloc(sizeof(Node));
   assert(p !=NULL );
   p->data = val;
   p->next = NULL;

   return p; 
}

void Push(PQueue pq,int val)
{
  Node *p = BuyNode(val);
  
  if(pq->front == NULL)
  {
    pq->front = p;
  }
  else
  {
    pq->rear->next = p;
  }
  pq->rear = p;
}

//获取队头的值,并删除
static bool Pop(PQueue pq,int *rtval)
{
   if(pq->rear == NULL)
   {
      return false;
   }
   
   Node * p = pq->front;
   *rtval = p->data;

   pq->front = p->next;
   free(p);
   
   if(pq->front == NULL)
   {
     pq->rear = NULL;
   }

   return true;
}

static int GetMaxFiguer(int *ar, int len)
{
  int max = arr[0];
  int count = 0;
  for(int i =0;i<len;i++)
  {
    if(max < arr[i])
    {
      max = arr[i];
    }
  }

  do
  {
    count++;
    max /= 10;
  }while(max !=0);

  return count;
}

//得到十进制数字num右数第figuer位的值
//figuer从0开始,如(123,0)-》3
static int GetFiguer(int num,int figuer)
{
  for(int i=0;i<figuer;i++)
  {
    num /=10;
  }
  return num %10;
}


//figuer为十进制数字右数第figuer位
//figuer从零开始
static Radix(int *arr,int lenient figuer)
{
  //创建10个队头
  HNode head[10];
  //依次初始化10个队头
  int i;
  for(i=0;i<10;i++)
  {
     lnitQueue(&head[i]);
      
  }
  
  for(i=0;i<len;i++)
  {
     key = GetFiguer(arr[i],figure);
     push(&head[key],arr[i]);
  }

  int j =0;
  for(i=0;i<len)
  {
    if(Pop(&head[j],&arr[i]))
    {
     i++;
    }
    else
    {
     j++;
    }
  }
  
}


void  RadixSort(int *arr,int len)
{
  int count = GetMaxFiguer(arr,len);
  for(int i =0;i<count;i++)
  {
     Radix(arr,len,i);
  }
}

int main()
{
  int arr[] ={1,34,56,43,23,38,89,27,5,9};
  
  RadixSort(arr,sizeof(arr)/sizeof(arr[0]));
  
  Show(arr,sizeof(arr)/sizeof(arr[0]));

}

高位优先用的少 ,就不写了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值