八种基本排序问题 (第七篇 基数排序)

一. 基数排序的描述

原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。

  • MSD:先从高位开始进行排序,在每个关键字上,可采用计数排序
  • LSD:先从低位开始进行排序,在每个关键字上,可采用桶排序

二.  实现思路

① 将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。
② 从最低位开始,依次进行一次排序。
③ 这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

排序的次数取决于最大数的位数

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
汉字的基数排序可以采用“按字排序”的方法,即按照汉字的拼音顺序进行排序。以下是一个基于C语言实现的汉字基数排序的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LENGTH 100 // 输入字符串的最大长度 // 获取字符串的第index个字符的拼音首字母 char getFirstLetter(char *str, int index) { char c = str[index]; if (c >= 'a' && c <= 'z') { return c; } else if (c >= 'A' && c <= 'Z') { return c + ('a' - 'A'); } else { // 汉字的拼音首字母 static int table[] = { -20319,-20317,-20304,-20295,-20292,-20283,-20265,-20257,-20242,-20230, -20051,-20036,-20032,-20026,-20002,-19990,-19986,-19982,-19976,-19805, -19784,-19775,-19774,-19763,-19756,-19751,-19746,-19741,-19739,-19728, -19725,-19715,-19540,-19531,-19525,-19515,-19500,-19484,-19479,-19467, -19289,-19288,-19281,-19275,-19270,-19263,-19261,-19249,-19243,-19242, -19238,-19235,-19227,-19224,-19218,-19212,-19038,-19023,-19018,-19006, -19003,-18996,-18977,-18961,-18952,-18783,-18774,-18773,-18763,-18756, -18741,-18735,-18731,-18722,-18710,-18697,-18696,-18526,-18518,-18501, -18490,-18478,-18463,-18448,-18447,-18446,-18239,-18237,-18231,-18220, -18211,-18201,-18184,-18183,-18181,-18012,-17997,-17988,-17970,-17964, -17961,-17950,-17947,-17931,-17928,-17922,-17759,-17752,-17733,-17730, -17721,-17703,-17701,-17697,-17692,-17683,-17676,-17496,-17487,-17482, -17468,-17454,-17433,-17427,-17417,-17202,-17185,-16983,-16970,-16942, -16915,-16733,-16708,-16706,-16689,-16664,-16657,-16647,-16474,-16470, -16465,-16459,-16452,-16448,-16433,-16429,-16427,-16423,-16419,-16412, -16407,-16403,-16401,-16393,-16220,-16216,-16212,-16205,-16202,-16187, -16180,-16171,-16169,-16158,-16155,-15959,-15958,-15944,-15933,-15920, -15915,-15903,-15889,-15878,-15707,-15701,-15681,-15667,-15661,-15659, -15652,-15640,-15631,-15625,-15454,-15448,-15436,-15435,-15419,-15416, -15408,-15394,-15385,-15377,-15375,-15369,-15363,-15362,-15183,-15180, -15165,-15158,-15153,-15150,-15149,-15144,-15143,-15141,-15140,-15139, -15128,-15121,-15119,-15117,-15110,-15109,-14941,-14937,-14933,-14930, -14929,-14928,-14926,-14922,-14921,-14914,-14908,-14902,-14894,-14889, -14882,-14873,-14871,-14857,-14678,-14674,-14670,-14668,-14663,-14654, -14645,-14630,-14594,-14429,-14407,-14399,-14384,-14379,-14368,-14355, -14353,-14345,-14170,-14159,-14151,-14149,-14145,-14140,-14137,-14135, -14125,-14123,-14122,-14112,-14109,-14099,-14097,-14094,-14092,-14090, -14087,-14083,-13917,-13914,-13910,-13907,-13906,-13905,-13896,-13894, -13878,-13870,-13859,-13847,-13831,-13658,-13611,-13601,-13406,-13404, -13400,-13398,-13395,-13391,-13387,-13383,-13367,-13359,-13356,-13343, -13340,-13329,-13326,-13318,-13147,-13138,-13120,-13107,-13096,-13095, -13091,-13076,-13068,-13063,-13060,-12888,-12875,-12871,-12860,-12858, -12852,-12849,-12838,-12831,-12829,-12812,-12802,-12607,-12597,-12594, -12585,-12556,-12359,-12346,-12320,-12300,-12120,-12099,-12089,-12074, -12067,-12058,-12039,-11867,-11861,-11847,-11831,-11798,-11781,-11604, -11589,-11536,-11358,-11340,-11339,-11324,-11303,-11097,-11077,-11067, -11055,-11052,-11045,-11041,-11038,-11024,-11020,-11019,-11018,-11014, -10838,-10832,-10815,-10800,-10790,-10780,-10764,-10587,-10544,-10533, -10519,-10331,-10329,-10328,-10322,-10315,-10309,-10307,-10296,-10281, -10274,-10270,-10262,-10260,-10256,-10254 }; int i = (c & 0xff) + ((c >> 8) & 0xff) * 256; if (i < 0xB0A1) { return 'A'; } else if (i < 0xB0C5) { return 'B'; } else if (i < 0xB2C1) { return 'C'; } else if (i < 0xB4EE) { return 'D'; } else if (i < 0xB6EA) { return 'E'; } else if (i < 0xB7A2) { return 'F'; } else if (i < 0xB8C1) { return 'G'; } else if (i < 0xB9FE) { return 'H'; } else if (i < 0xBBF7) { return 'J'; } else if (i < 0xBFA6) { return 'K'; } else if (i < 0xC0AC) { return 'L'; } else if (i < 0xC2E8) { return 'M'; } else if (i < 0xC4C3) { return 'N'; } else if (i < 0xC5B6) { return 'O'; } else if (i < 0xC5BE) { return 'P'; } else if (i < 0xC6DA) { return 'Q'; } else if (i < 0xC8BB) { return 'R'; } else if (i < 0xC8F6) { return 'S'; } else if (i < 0xCBFA) { return 'T'; } else if (i < 0xCDDA) { return 'W'; } else if (i < 0xCEF4) { return 'X'; } else if (i < 0xD1B9) { return 'Y'; } else if (i < 0xD4D1) { return 'Z'; } else { return ' '; } } } // 计数排序 void countingSort(char **strs, int n, int index) { int counts[26] = {0}; // 记录每个字母出现的次数 char **temp = (char **)malloc(sizeof(char *) * n); for (int i = 0; i < n; i++) { temp[i] = (char *)malloc(sizeof(char) * MAX_LENGTH); strcpy(temp[i], strs[i]); } for (int i = 0; i < n; i++) { char c = getFirstLetter(strs[i], index); counts[c - 'A']++; } for (int i = 1; i < 26; i++) { counts[i] += counts[i - 1]; } for (int i = n - 1; i >= 0; i--) { char c = getFirstLetter(strs[i], index); int pos = counts[c - 'A'] - 1; strcpy(temp[pos], strs[i]); counts[c - 'A']--; } for (int i = 0; i < n; i++) { strcpy(strs[i], temp[i]); free(temp[i]); } free(temp); } // 基数排序 void radixSort(char **strs, int n) { int maxLength = 0; for (int i = 0; i < n; i++) { int length = strlen(strs[i]); if (length > maxLength) { maxLength = length; } } for (int i = maxLength - 1; i >= 0; i--) { countingSort(strs, n, i); } } int main() { int n; char **strs; printf("请输入字符串的数量:"); scanf("%d", &n); strs = (char **)malloc(sizeof(char *) * n); printf("请输入%d个字符串,每个字符串长度不超过%d个字符:\n", n, MAX_LENGTH); for (int i = 0; i < n; i++) { strs[i] = (char *)malloc(sizeof(char) * MAX_LENGTH); scanf("%s", strs[i]); } radixSort(strs, n); printf("排序后的结果为:\n"); for (int i = 0; i < n; i++) { printf("%s\n", strs[i]); free(strs[i]); } free(strs); return 0; } ``` 代码中使用了计数排序基数排序两个算法。在计数排序中,通过`getFirstLetter()`函数获取每个字符串的第`index`个字符的拼音首字母,并统计各个字母出现的次数。然后按照字母顺序从小到大填充到一个临时数组中,最后将临时数组中的元素复制回原数组。在基数排序中,依次对每个字符进行计数排序,直到排完所有字符。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是小晴晴呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值