基本算法-基数排序

简介: 基本算法-基数排序

前言

      本文介绍一种排序算法——基数排序,是经典排序算法之一。以下是本篇文章正文内容,包括算法简介、算法特点、算法实现和C++示例。

一、基数排序简介

      基数排序不需要进行元素之间的比较操作,而是一种分配模式排序方式。基数排序法按比较的方向可分为最高位优先(Most Significant Digit First,MSD)和最低位优先(Least Significant Digit First,FSD)两种。MSD是从最左边的位数开始比较,而LSD则是从最右边的位数开始比较。一般常选择LSD。


      基数排序法的实现思路:


  1. 计算数列最大值,并确认其位数。
  2. 从最高位或最低位开始,结合临时创建的二维数组,进行放置操作;合并数据完成当前位数级的排序。
  3. 位数递减或递增,按上述操作执行,直到所有位数遍历过一遍,此时完成排序。

二、算法特点

      1)所有情况下的时间复杂度为O(kn)。但是这个常数k蛮大的,并不能因为复杂度是n就觉得它一定快。


      2)稳定,合并过程不改变原序列过程。


      3)空间复杂度是O(n*p),需要用很大的额外空间做辅助,p是最大位数,比如1000的位数是4。

三、代码实现

      代码实现逻辑:

  1. 确认最大值。
  2. 计算最大位数。
  3. 从最左或最右位数,按位数放置在二维数组中,并重新组建新数列。
  4. 所有位数遍历一遍,此时数列完成排序。
// 基数排序
void RadixSort(vector<int> &data)
{
  // 确认最大值
  int size = int(data.size());
  int max = data[0];
  for (int i = 1; i < size; ++i)
  {
    if (data[i] > max)
      max = data[i];
  }
  // 计算位数
  int n = 1;
  int temp = max / 10;
  while (temp != 0)
  {
    temp /= 10;
    n++;
  }
  // 主过程
  int b = 1;
  for (int k = 1; k <= n; ++k)
  {
    // 初始化二维数组
    vector<vector<int>> tmp(10, vector<int>(size, -1));
    // 根据b位数级数字,放置在对应位置
    for (int i = 0; i < size; ++i)
    {
      int m = (data[i] / b) % 10;
      tmp[m][i] = data[i];
    }
    // 依次放回data
    int p = 0;
    for (int i = 0; i < 10; ++i)
    {
      for (int j = 0; j < size; ++j)
      {
        if (tmp[i][j] != -1)
        {
          data[p] = tmp[i][j];
          p++;
        }
      }
    }
    b *= 10;
  }
}

四、C++示例

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <opencv2/opencv.hpp>
#include <fstream>
#include <sstream>
#include <armadillo>
#include <math.h>
#include <assert.h>
using namespace std;
using namespace cv;
#define M_PI 3.1415
// 展示当前顺序
void Show(vector<int> data)
{
  size_t size = data.size();
  for (size_t i = 0; i < size; ++i)
    cout << setw(6) << data[i];
  cout << endl;
}
// 基数排序
void RadixSort(vector<int> &data)
{
  cout << "基数排序:\n原始数据:\n";
  Show(data);
  // 确认最大值
  int size = int(data.size());
  int max = data[0];
  for (int i = 1; i < size; ++i)
  {
    if (data[i] > max)
      max = data[i];
  }
  // 计算位数
  int n = 1;
  int temp = max / 10;
  while (temp != 0)
  {
    temp /= 10;
    n++;
  }
  // 主过程
  int b = 1;
  for (int k = 1; k <= n; ++k)
  {
    // 初始化二维数组
    vector<vector<int>> tmp(10, vector<int>(size, -1));
    // 根据b位数级数字,放置在对应位置
    for (int i = 0; i < size; ++i)
    {
      int m = (data[i] / b) % 10;
      tmp[m][i] = data[i];
    }
    // 依次放回data
    int p = 0;
    for (int i = 0; i < 10; ++i)
    {
      for (int j = 0; j < size; ++j)
      {
        if (tmp[i][j] != -1)
        {
          data[p] = tmp[i][j];
          p++;
        }
      }
    }
    b *= 10;
    cout << "第" << k << "次排序结果:\n";
    Show(data);
  }
  cout << "排序后结果:\n";
  Show(data);
}
// 主函数
int main()
{
  vector<int> data = { 9,11,567,0,26,4,2,12,18,6,9,5378,102,8 };
  // 基数排序
  RadixSort(data);
  system("pause");
  return 0;
}

     效果图:

      综上所述,基数排序的空间复杂度过大,而时间复杂度因为常数项的存在,也并没有优于其他算法多少,最主要的是需要先确定好基数才能排序,这有点鸡肋,因此个人不太建议使用,但是原理要清楚~

      如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

相关文章
|
6月前
|
算法 搜索推荐 Python
Python算法——基数排序
Python算法——基数排序
62 1
|
3月前
|
搜索推荐 算法 Java
【数据结构排序算法篇】----基数排序【实战演练】
【数据结构排序算法篇】----基数排序【实战演练】
30 3
|
4月前
|
算法 搜索推荐 Java
数据结构与算法面试:基于比较的排序算法时间复杂度最坏情况下是 O(nlogn),请问有没有更快的算法?(提示:计数排序、基数排序)
数据结构与算法面试:基于比较的排序算法时间复杂度最坏情况下是 O(nlogn),请问有没有更快的算法?(提示:计数排序、基数排序)
21 0
|
4月前
|
存储 搜索推荐
常见排序算法原理——第三部分(桶排序、计数排序、基数排序)
常见排序算法原理——第三部分(桶排序、计数排序、基数排序)
|
9月前
|
存储 算法 搜索推荐
数据结构各内部排序算法总结对比及动图演示(插入排序、冒泡和快速排序、选择排序、堆排序、归并排序和基数排序等)2
数据结构各内部排序算法总结对比及动图演示(插入排序、冒泡和快速排序、选择排序、堆排序、归并排序和基数排序等)2
168 0
|
10月前
|
存储 搜索推荐 算法
八大排序算法-直接插入排序、希尔排序、直接选择排序、冒泡排序、堆排序、快速排序、归并排序、基数排序(下)
八大排序算法-直接插入排序、希尔排序、直接选择排序、冒泡排序、堆排序、快速排序、归并排序、基数排序(下)
|
10月前
|
搜索推荐 算法 Java
【算法】基数排序的原理与Java实现
基数排序(Radix Sort)是一种非比较性的排序算法,它根据元素的位数逐位进行排序。基数排序的核心思想是将待排序的元素按照低位到高位的顺序进行排序,每一位都使用稳定的排序算法(通常是计数排序或桶排序)。通过多次按位排序,最终可以得到有序的结果
71 0
|
5月前
|
算法 搜索推荐 C语言
【408数据结构与算法】—基数排序(桶排序)(二十三)
【408数据结构与算法】—基数排序(桶排序)(二十三)
|
6月前
|
存储 搜索推荐 C#
C#基数排序算法
C#基数排序算法
|
7月前
|
搜索推荐 算法
深入浅出排序算法之基数排序
深入浅出排序算法之基数排序