算法导论笔记(五) :基数排序与C++实现

1 基数排序介绍

基数排序是一种用在老式穿卡机上的算法。

该算法在对每一位数进行排序的时候需要是稳定的:

在该为相同的数的相对顺序不会变.因此可以使用上节的计数排序作为其子程序.

下边演示一个基数排序的过程:


2 基数排序的过程

计数排序的过程很简单。即从最低位到最高位的每一位进行计数排序.

3 算法实现

#ifndef __RADIXSORT_H__
#define __RADIXSORT_H__

#include <malloc.h>
#include <time.h>
#include <stdlib.h>

class Radixsort
{
  int* m_data_input;
  int* m_data_output;
  int* m_data_tmp;
  int* m_counter;
  int m_size;
  int m_max;
public:
  Radixsort(int size,int maxValue);
  ~Radixsort();
  void Create();
  void Sort();
  bool Counter(int digit);
  bool Verify();
  void OutputResult();
};

#endif

#include "Radixsort.h"
#include <stdio.h>
Radixsort::Radixsort(int size ,int maxValue)
{
  m_size = size;
  m_max = maxValue;
  m_data_input = (int*)malloc(sizeof(int)* size);
  m_data_output = (int*)malloc(sizeof(int)* size);
  m_data_tmp = (int*)malloc(sizeof(int)* size);
  m_counter = (int*)malloc(sizeof(int)* maxValue);
}

Radixsort::~Radixsort()
{
  if(m_data_input)
  {
    free(m_data_input);
    free(m_data_output);
    free(m_counter);
    free(m_data_tmp);
  }
}

void Radixsort::Create()
{
  srand((unsigned)time(NULL));
  for(int i=0;i< m_size;i++)
  {
    m_data_input[i] = rand() % m_max;
  }
}

bool Radixsort::Counter(int digit)
{
  bool bContinue = false;
  for(int i=0;i<10;i++)
  {
    m_counter[i] = 0;
  }
  for(int j=0;j<m_size;j++)
  {
    int tmp = m_data_input[j] / digit;
    m_data_tmp[j] = tmp % 10;
    m_counter[m_data_tmp[j]]++;
    if(tmp)
    {
      bContinue = true;
    }
  }
  for(int i=1;i<10;i++)
  {
    m_counter[i] = m_counter[i] + m_counter[i-1];
  }
  for(int v = m_size-1;v>=0;v--)
  {
    m_data_output[m_counter[m_data_tmp[v]]-1] = m_data_input[v];
    m_counter[m_data_tmp[v]]--;
  }
  if(bContinue)
  {
    int* tmp = m_data_output;
    m_data_output = m_data_input;
    m_data_input = tmp;
  }

  return bContinue;
}

void Radixsort::Sort()
{
  int digit = 1;
  while(Counter(digit))
  {
    digit *=10;
  }
}

bool Radixsort::Verify()
{
  int oldValue = m_data_output[0];
  for(int i=1;i<m_size;i++)
  {
    if(m_data_output[i]<oldValue)
    {
      return false;
    }
    oldValue = m_data_output[i];
  }
  return true;
}

void Radixsort::OutputResult()
{
  for(int i=0;i<m_size;i++)
  {
    printf("%d \n",m_data_output[i]);
  }
}

#include "Radixsort.h"
#include <stdio.h>

int main()
{
  int maxValue = 1000;
  int size = 20;
  Radixsort pSort(size,maxValue);
  pSort.Create();
  pSort.Sort();
  if(pSort.Verify())
  {
    printf("Success ! \n");
    pSort.OutputResult();
  }
  else
  {
    printf("Error ! \n");
  }
  return 0;
}


4 性能分析

基数排序不是基于比较的排序,其运行时间为O(n),这是好于快速排序的平均情况O(nlgn).

但是其隐藏的常数因子通常要比快速排序大很多.并且它不是原地排序。因此基数排序只在排序规模很大

但又内存足够的时候才会有一定优势。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值