当前位置: 首页 > news >正文

排序算法————基数排序(RadixSort)

基数排序的概念:

什么是基数排序???基数排序是一种和快排、归并、希尔等等不一样的排序...它不需要比较和移动就可以完成整型的排序。它是时间复杂度是O(K*N),空间复杂度是O(K+M


基数排序的思想: 

  • 基数排序是一种借助多关键字的思想对单逻辑关键字进行排序的方法。
  • 基数排序根据每个位来分配桶,怎么理解呢???看下面的动图,0-9就是所分配的桶
  • 用大白话来说,基数排序就是先分发数据再回收数据,可以看看下面的动图。

181965eaa5e249518e426b17fcc6d02a.gif


  •  接下来,跟着我的思路走,你也可以实现它。如下面代码,我先定义了一个数组,然后求出来了它的个数。然后就进入基数排序。
int main()
{int arr[10] = { 278,109,63,930,589,183,505,269,83,8 };int n = sizeof(arr) / sizeof(int);for (int i = 0; i < n; i++){cout << arr[i] << " ";}cout << endl;//基数排序RadixSrot(arr, 0, n);for (int i = 0; i < n; i++){cout << arr[i] << " ";}cout << endl;return 0;
}

 


RadixSort函数实现:

  • 思想就是先分发再回收数据。这里的K,我是用宏来定义的,因为我所创建的arr数组最多也就是到了百位,所以其实我们分发3次数据就可以回收了。
#define K 3
void RadixSrot(int arr[],int left,int right) //[left,right)
{for (int i = 0; i < K; i++){//分发数据Distribute(arr, left, right, i);//回收数据Collect(arr);}
}

分发数据的实现:

  • 分发数据中,我用key来接受了每次分发数据后的值。
  • 下面我来演示它每一次的排序情况。
  • 桶其实就是0-9:
  •  0         1          2        3        4        5         6          7           8            9   
  •  930                         63              505                               278        109
  •                               183                                                        8       589
  •                                  83                                                                269  

然后第一次排序完就是:930  63 183 83 505 278 8 109 589 269

  •  0         1          2        3        4        5         6          7           8            9   
  •   505                         930                         63       278        183
  • 008                                                           269                  083
  • 109                                                                                    589

第二次排序完就是  505   008   109   930   63   269   278   183    038   589

第三次排序完:8   63   83   109   183   269   278   505   589   930

 

  • 它的思想就是这样,也因为它是先分发的数据先回收,所以我定义了10个int的队列,因为考虑最坏情况(如果个位数全部是一样的),得到分发过后的个位数后,我就将数字插入到对应的队列中。然后回收,因为是先分发先回收,队列特性刚好满足,就将队列中的数放到数组中,这就完成了第一次的排序。因为都是百位数,所以最多是3次,就用上面的图中的for循环来完成接下里的排序。

 

#define RADIX 10//定义基数  构造了10个int的队列
queue<int> Q[RADIX];void Distribute(int arr[],int left,int right,int k)
{for (int i = left;i < right; i++){int key = GetKey(arr[i], k);Q[key].push(arr[i]);}}
int GetKey(int value, int k)
{int key = 0;while (k >= 0){key = value % 10;value /= 10;k--;}return key;
}

 


 下面是源码:

#define  _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <queue>
using namespace std;#define K 3
#define RADIX 10//定义基数  构造了10个int的队列
queue<int> Q[RADIX];//value : 278
//k =0 的时候 就得到8  k=1 就得到7
int GetKey(int value, int k)
{int key = 0;while (k >= 0){key = value % 10;value /= 10;k--;}return key;
}//k代表了第几次分发数据
void Distribute(int arr[],int left,int right,int k)
{for (int i = left;i < right; i++){int key = GetKey(arr[i], k);Q[key].push(arr[i]);}}void Collect(int arr[])
{int k = 0;for (int i = 0; i < RADIX; i++){while (!Q[i].empty()){arr[k++] = Q[i].front();Q[i].pop();}}
}void RadixSrot(int arr[],int left,int right) //[left,right)
{for (int i = 0; i < K; i++){//分发数据Distribute(arr, left, right, i);//回收数据Collect(arr);}
}int main()
{int arr[10] = { 278,109,63,930,589,183,505,269,83,8 };int n = sizeof(arr) / sizeof(int);for (int i = 0; i < n; i++){cout << arr[i] << " ";}cout << endl;//基数排序RadixSrot(arr, 0, n);for (int i = 0; i < n; i++){cout << arr[i] << " ";}cout << endl;return 0;
}

 

 

http://www.lryc.cn/news/120714.html

相关文章:

  • leetcode做题笔记75颜色分类
  • 聊一下互联网开源变现
  • PHP日期差计算器,计算两个时间相差 年/月/日
  • 20230812在WIN10下使用python3将SRT格式的字幕转换为SSA格式
  • matlab使用教程(13)—稀疏矩阵创建和使用
  • UI美工设计的主要职责(合集)
  • 【前端二次开发框架关于关闭eslint】
  • Scractch3.0_Arduino_ESP32_学习随记_蓝牙键盘(三)
  • Spark2.2出现异常:ERROR SparkUI: Failed to bind SparkUI
  • LeetCode 2811. Check if it is Possible to Split Array【脑筋急转弯;前缀和+动态规划或记忆化DFS】中等
  • 【学习日记】【FreeRTOS】链表结构体及函数详解
  • 【云原生•监控】基于Prometheus实现自定义指标弹性伸缩(HPA)
  • Windows、 Linux 等操作系统的基本概念及其常见操作
  • 【RabbitMQ】golang客户端教程5——使用topic交换器
  • SpringBoot对接OpenAI
  • (C++)继承
  • 图像处理技巧形态学滤波之膨胀操作
  • 机器学习基础之《特征工程(4)—特征降维》
  • 学生管理系统(Python版本)
  • Linux下快速创建大文件的4种方法总结
  • 用 Rufus 制作 Ubuntu 系统启动盘时,选择分区类型为MBR还是GPT?
  • Nodejs+vue+elementui汽车租赁管理系统_1ma2x
  • Prometheus入门
  • RISC-V云测平台:Compiling The Fedora Linux Kernel Natively on RISC-V
  • Vim学习(三)—— Git Repo Gerrit
  • 论坛项目之用户部分
  • golang内存对齐
  • 【CheatSheet】Python、R、Julia数据科学编程极简入门
  • 【golang】怎样判断一个变量的类型?
  • 怎么学习AJAX相关技术? - 易智编译EaseEditing