2.基数排序(Radix Sort)-提升C++版本

1.思想
1.如果比较的数字不一样长度,数位较短的数前面补零 如68,351 那么 68 变成 068

2.从最低位开始, 依次进行一次稳定排序( 因为每个数字的位数的取值范围是固定的从0到9,个位,十位,百位,千位).这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列.

2.再次理解:
A.s[] 中倒入Ls[]
B. 然后Ls[] 倒回 s[] 中 重复A,B步骤 直到结束
就是将原来乱序的数组s[] 初次排序后倒入Ls[],然后再倒回s[],比方说,按照每个元素的十位上的数字已经排好序
3.每次按照 个,十,百。。。位 进行比较 ,小的放前
在这里插入图片描述
4.两个问题:
为什么要从低位开始向高位排序?
在数学中, 数位越高,数位值对数的大小的影响就越大.从低位开始排序,就是对这种影响的排序. 数位按照影响力从低到高的顺序排序, 数位影响力相同则比较数位值.

为什么同一数位的排序子程序要使用稳定排序?
稳定排序的意思是指, 待排序相同元素之间的相对前后关系,在各次排序中不会改变.比如实例中具有十位数字5的两个数字58和356, 在十位排序之前356在58之前,在十位排序之后, 356依然在58之前.

稳定排序能保证,上一次的排序成果被保留,十位数的排序过程能保留个位数的排序成果,百位数的排序过程能保留十位数的排序成果.
5.代码解析

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

=====================================================
--------------------------------------------重要思考-------------------------------

元素所在Ls[k]中序列位置与每个元素的个、十、百位上的数字有关,
每次重复步骤都有可能打乱上次s[]中顺序,
只是第一次是按照每个元素的个位排列从小到大放,
第二次按照之前个位排列好的新的序列s[ ]中的每个元素的
十位上的数字排列再次排列从小到大放,
第三次按照之前十位上的数字排列好的新的序列s[ ]中每个元素的
百位上的数字排列再次排列从小到大放,依次类推。。。

在这里插入图片描述
6.关键
1.k如何得到??就是根据数组中元素数字的第某个数字位上的数字得到k
2.得到这个k 决定了 放在Ls[]中第k位置上的元素s[i]
7.生动形象的例子例如:
A.待排序数组[62,14,59,88,16] 五个数字
s[] 中倒入Ls[]

分配10个桶,桶编号为0-9,以数组上每个元素的个位上的数字为对应桶编号依次入桶,变成下边这样在这里插入图片描述
B.将桶里的数字顺序取出来, Ls[] 倒回 s[] 中
输出结果:[62,14,16,88,59]

C.再次入桶
不过这次以数组上每个元素的十位上的数字为对应桶编号依次入桶,变成下边这样
在这里插入图片描述
由于前边做了按照每一个元素的个位数上的数字进行了排序,所以当每个元素的上数字以十位上的数字数相等时,个位上的数字是由小到大的顺序入桶的,就是说,入完桶还是有序

因为没有大过100的数字,没有百位数,所以到这排序完毕,顺序取出即可

最后输出结果:[14,16,59,62,88]

8.贴代码
1.头文件中*

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;

2.核心代码

#include "stdafx.h"

 int k=1;
void Output(string s[], int n)
{  
	for(int i=0; i<n; i++)
		cout<<s[i]<<"  ";
	cout<<"第"<<k++<<"次结果"<<endl;

}

void RadixSort(string s[], int n, int d)
{
	list<string> Ls[10];
	for(int d1=d-1; d1>=0; d1--)
	{
		for(int i=0;i<10; i++)
			Ls[i].clear();//对每一个元素清空Ls[i],迎接再次新的排序
		for(i=0; i<n; i++)	{
			int k=s[i][d1]-'0';
		//k得到值是根据d1的值
		//s[i][d1]表示取第i个元素的第d1位
		//s[0]=986,故s[0][2]-'0'为该元素的下标2元素	是数字6,作为下标位置s[6]放入s[i]
			Ls[k].push_back(s[i]);//下标位置s[6]相当于Ls[6]位置放入s[i]对应元素
		}
		int k=0;
		for(i=0; i<10; i++)
		{//这个是将数据倒出来,倒入字符串数组s[] 中,形成新的序列
			for(list<string>::iterator it=Ls[i].begin(); it!=Ls[i].end(); it++)
				s[k++]=*it;//【k++】++后取前  所以当k=0时,初始值s[k++]=s[0]
		}//此时s[]内容已不再是原来的顺序,而是按照某位的顺序排的了
		Output(s, n);//某位意思是根据d1的变化而变化的
	}
}

int main(int argc, char* argv[])
{
	string s[]={"986","321","123","432","500",
				"654","018","765","987","210"};
	
	//n代表字符串数组长度  d代表元素占的位数 个、十、百、千位
	int n=10, d=3;
	RadixSort(s, n, d);
	return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值