您的位置:首页 > 其它

算法记录:MSD基数排序 + qsort 对字符串排序

2008-02-20 01:42 393 查看
typedef std::vector<std::string> t_vstr;
void exch(std::string &str1, std::string &str2)
{
std::swap(str1, str2);
}
void str_qsort_internal(t_vstr &arr, int l, int r, size_t d)
{
if(l >= r)return;
int i = l - 1, j = r;
int p = i, q = j;
char v = arr[r][d];
while(i < j)
{
while(arr[++i][d] < v); //i是第一个大于等于v的索引,可能等于r(到r时一定停止循环)
while(v < arr[--j][d]) {if(j == l) break; } //j是第一个小于等于v的,当j == l时循环也会结束,例如所有元素都比arr[r]大

if(i > j) break;
exch(arr[i], arr[j]); //交换,要么是arr[i] >= v && arr[j] <= v 之后 arr[i] <= v && arr[j] >= v
if(arr[i][d] == v) exch(arr[i], arr[++p]);//arr[p]一定小于等于v,
if(arr[j][d] == v) exch(arr[j], arr[--q]); //arr[q]一定大于等于v
}

if(p == q)//如果p == q则证明l -> r区间全相等
{
if(v != '/0')str_qsort_internal(arr, l, r, d + 1);//如果不为字符串结尾,则转换到下一层,如果v为'/0'则证明排序完毕
return;
}

if(arr[i][d] < v)i++;
/*
下面两个移动算法类似下图
p
4,4,4,1,2,3
k j
3,4,4,1,2,4
k j
3,2,4,1,4,4
k j
3,2,1,4,4,4
j 4
p
4,4,4,4,2
k j
2,4,4,4,4
k j
2,4,4,4,4
kj
2,4,4,4,4
j k
*/
for(int k = l; k <= p; ++k, --j) exch(arr[k], arr[j]); //l -> j区间元素都是小于等于v的,而l -> p都是等于v的,
for(int k = r; k >= q; --k, ++i) exch(arr[k], arr[i]); //i->r区间元素都是大于等于v的,而i->r都是等于v的
str_qsort_internal(arr, l, j, d);//因为i -> j区间内不一定都是相同的,但一定都小于等于v
if((i == r) && (arr[i][d] == v)) i++;//这里,如果i == r && arr[i][d] == v,则证明从j + 1到 r都是相同的元素,所以i+=1照应下一步的 i - 1 和str_qsort_internal(arr, i, r, d);因为i + 1之后,i 就一定大于r了

if(v != '/0') str_qsort_internal(arr, j + 1, i - 1, d+1);//如果v == 0,那么j+1 -> i-1区间内的所有字符串都为结尾,所以无需递归排序了
str_qsort_internal(arr, i, r, d);//同理,因为i -> 区间内不应定都是相同的,但一定都大于等于v, 因此搜索层次还是d
}

void print_vstr(const t_vstr &vstr)
{
for(size_t i = 0; i < vstr.size(); ++i)
{
printf("%s/n", vstr[i].c_str());
}
}

int main()
{
t_vstr vstr;

vstr.push_back("9");
vstr.push_back("123");
vstr.push_back("232");
vstr.push_back("234");
vstr.push_back("456");
vstr.push_back("789");
vstr.push_back("259");
vstr.push_back("257");

str_qsort_internal(vstr, 0, vstr.size() - 1, 0);
print_vstr(vstr);

printf("done/n");
cin.get();
return 0;
};

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: