基数排序!

本文详细介绍了基数排序的基本思想,包括LSD和MSD两种方法。基数排序通过队列的先进先出特性,从低位到高位或高位到低位进行排序,避免了比较和交换的过程。文中还给出了具体的图解和C++代码实现,帮助读者理解和应用基数排序算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 基数排序的基本思想

不同于之前的八大排序算法,那些排序算法都是依靠比较或者交换来入手的,因此对上述算法进行优化,也是从这两个方面入手的。

基数排序:最基本的两个思想是发数据和收数据

但是基数排序就没有这方面的考虑了

他有两种做法,但是两种做法都会依赖一个数据结构:队列,先进先出的性质。

1 LSD-》从最低位置开始排序

首先我们需要选定基数,所谓的基数就是比较的数字,以十进制数字为例子,由于每一个位置上的数字都是0——9,因此基数的选择就是0——9.

从最低位置排序:依次比较数列中的每一个数字的最低位置,并且把它放在对应的保存基数的队列中,如果排升序,那么这些队列就小到大进行排序。如果有相同的,就入栈。

等把上述的数列中的数字都放在了下面的数列组成的数组中的时候,发数据就完成了。那么接下来我们需要收数据了,从前往后依次出队列。这样子我们第一次排序得到的数据就是个位按照升序排好的数据了

这是第一趟排序

完了之后我们排第二趟数据的时候是根据十位的数字进行排序的,也是按照上述的思想。等到将数组中所有的都排完之后,这个数列就完成了排序

如何确定所有的都排完了呢?这个数组中最多位数的一个数字就是这个数组需要排列的趟数。如果有些数字位数不同,就在比较小的数字前面补上0就行了

2 MSD-》从最高位进行排序

了解了LSD之后其实MSD也是好理解的,只不过排序的顺序从最低位到最高位变成了从最高位到最低位置

二 图解

第一次排序 个位数字被排好了

 

动图:(网上找的)

三 代码:

#define _CRT_SECURE_NO_WARNINGS 1 
#include<iostream>
#include<queue>
#include<assert.h>
using namespace std;

#define Radix 10
#define K 3

queue<int>q[Radix];

void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		cout<<a[i]<<" ";
	}
}
int Getkey(int num,int k)
{
	
	int ret = 0;
	while (k >= 0)
	{
		k--;
		ret = num % 10;
		num /= 10;
	}
	return ret;
}
void Send(int* a, int n,int k)
{
	assert(a);
	
		for (int i = 0; i < n; i++)
		{
				int key = Getkey(a[i], k);
				q[key].push(a[i]);
		}
	

}

void Collection(int* a, int n, int k)
{
	        assert(a);
			int i = 0;
			for (int k = 0; k < Radix; k++)
			{
				while (!q[k].empty())
				{
					a[i++] = q[k].front();
					q[k].pop();
				}
			}
}
void RadixSort(int* a, int n)
{
	    assert(a);
		for (int k = 0; k < K; k++)
		{
			Send(a, n, k);
			Collection(a, n, k);
		}
}
int main()
{
	int arr[] = { 278,109,63,930,589,184,505,269,8,83 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	
	cout << "基数排序前:";
	Print(arr, sz);
	cout << endl;

	RadixSort(arr, sz);

	cout << "基数排序后:";
	Print(arr, sz);
	cout << endl;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值