8-3 排序不同长度的数据项
a)给定一个整数数组,其中不同的整数中包含的数字个数可能不同,但该数组中,所有整数中的总的数字数为n。说明如何在O(n)的时间内对该数组进行排序。
b)给定一个字符串数组,其中不同的串包含的字符数可能不同,但所有串中总的字符个数为n。说明如何在O(n)时间内对该数组进行排序。(注意此处的顺序是指标准的字母顺序,例如a<ab<b)
分析与解答:
a)如果采用平常的基数排序,从最低位到最高位开始排序,考虑最坏的情况:如果最长的整数的字数为n/2,其他n/2个整数的字数为1,则采用基数排序,时间复杂度为Θ(n^2)。
注意到这样一个非常重要的现象:不失一般性,先不考虑整数的正负,那么字数少的整数一定小于字数多的整数。
假设字数为i的整数的个数为mi,则
如果所有整数的个数为m,显然有m≤ n。首先按字数对所有的整数进行计数排序,时间复杂度为Θ(n+m),也即Θ(n)。 然后对于相同字数的整数进行基数排序,时间复杂度为Θ(i*mi),那么总的时间复杂度为
b)对于字符串则采用类似的方法,注意到这样的现象:因为是字典序,那么只要前面的字母比较小,就不用比较后面的字母了。比如abxxx<acxxx,一旦发现b<c之后就确定关系了,而不管后面的xxx是啥。
因此我们可以从左到右进行比较,假定字符串以'/0'结尾。我们从左到右进行基数排序。一次计数排序完成后,我们只需要对当前字符相同的各个类别分别进行排序,将当前排序问题分成多个独立的子问题,如此迭代的进行。在排序完成后一旦发现当前字符为结束符,则不用参与下次比较了,迭代的进行即可。也就是说,长度为i的字符串最多比较的次数为i+1,则总的时间复杂度为