基本算法-基数排序
Posted 翟天保Steven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基本算法-基数排序相关的知识,希望对你有一定的参考价值。
作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
前言
本文介绍一种排序算法——基数排序,是经典排序算法之一。以下是本篇文章正文内容,包括算法简介、算法特点、算法实现和C++示例。
一、基数排序简介
基数排序不需要进行元素之间的比较操作,而是一种分配模式排序方式。基数排序法按比较的方向可分为最高位优先(Most Significant Digit First,MSD)和最低位优先(Least Significant Digit First,FSD)两种。MSD是从最左边的位数开始比较,而LSD则是从最右边的位数开始比较。一般常选择LSD。
基数排序法的实现思路:
- 计算数列最大值,并确认其位数。
- 从最高位或最低位开始,结合临时创建的二维数组,进行放置操作;合并数据完成当前位数级的排序。
- 位数递减或递增,按上述操作执行,直到所有位数遍历过一遍,此时完成排序。
二、算法特点
1)所有情况下的时间复杂度为O(kn)。但是这个常数k蛮大的,并不能因为复杂度是n就觉得它一定快。
2)稳定,合并过程不改变原序列过程。
3)空间复杂度是O(n*p),需要用很大的额外空间做辅助,p是最大位数,比如1000的位数是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;
效果图:
综上所述,基数排序的空间复杂度过大,而时间复杂度因为常数项的存在,也并没有优于其他算法多少,最主要的是需要先确定好基数才能排序,这有点鸡肋,因此个人不太建议使用,但是原理要清楚~
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!
以上是关于基本算法-基数排序的主要内容,如果未能解决你的问题,请参考以下文章