小白学算法3.1——低位优先字符串排序

来源:互联网 发布:美国eia原油库存数据公布时间 编辑:程序博客网 时间:2024/05/20 11:47

小白学算法3.1——低位优先字符串排序

标签: 小白学算法 博客


本节内容总结自《算法(第4版)》5.1节

1.低位优先字符串排序

相比较于数字,字符串在生活中出现的频率更高,更常用,如姓名、车牌和电话号码等,而字符串常常也需要按照一定的顺序存放(一般是ASCII顺序),此时决定顺序的键就是字符串。字符串常见的排序算法有两种,分别是低位优先(LSD)和高位优先(MSD),低位优先从右向左检查字符,高位优先从左向右检查字符。

低位优先字符串排序要求待排序的字符串长度一致

低位优先字符串排序和基数排序非常的相似。假设字符串的长度为W,首先以最低位W-1位为键进行排序,再以W-2位为键进行排序,……,直到以0位为键进行排序,此时排序的结果就是最终的结果。显而易见,低位优先字符串排序是稳定排序。

2.低位优先字符串排序实现

假设现在有美国加州的一部分车牌号需要排序,存储在data.txt中,具体内容如下:

4PGC938
2IYE230
3CIO720
1ICK750
1OHV845
4JZY524
1ICK750
3CIO720
1OHV845
1OHV845
2RLA629
2RLA629
3ATW723

车牌号长度为7,所以从最低位到最高位依次排序7次,用循环解决。R表示字符串基数,即所有字符串中不同字符的个数,常常选为128或者256,因为7位或者8位的ASCII码能够表示大多数的字母字符串。

#include "stdafx.h"#include <IOSTREAM>#include <FSTREAM>#include <STRING>#include <VECTOR>const int W = 7;const int R = 128;using namespace std;int main(int argc, char* argv[]){    string str;    vector<string> sVec;    ifstream infile("data.txt");    cout<<"Before sort:"<<endl;    while (infile>>str)    {        cout<<str<<endl;        sVec.push_back(str);    }    int n = sVec.size();    vector<string> aux(n, "");    for ( int d=W-1; d>=0; d--)    {   //循环内是一个简单的算法:键索引计数        //计算频率        int count[R+1]={0};        for ( int i=0; i<n; i++)            count[sVec[i][d]+1]++;//此处下标加1存储,稍后解释        //将频率转化为索引        for ( int r=0; r<R; r++)            count[r+1] += count[r];        //将元素分类        for (int i=0; i<n; i++)            aux[count[sVec[i][d]]++] = sVec[i];        //回写        for (int i=0; i<n; i++)            sVec[i] = aux[i];    }    cout<<"After sort:"<<endl;    for (int i=0; i<n; i++)        cout<<sVec[i]<<endl;    return 0;}

在计算频率的过程中,下标加1存储,是为了访问count[]数组对应的位置时可以直接获取aux[]中的对应下标,举个例子:

现在有4个小组,记为1~4组,分别有3,5,6,6个人,则根据键值+1作为下标的存储规则,count[]数组的值为{0,0,3,5,6,6},将频率转化为索引后为count[]={0,0,3,8,14,20},元素分类的过程中根据count[]中元素的数值来存放数据到aux[]中的指定位置,此时第i组的起始下标恰恰就是count[i],如第1组起始下标为0,第2组起始下标为3.

排序过程如下:

排序结果:

3.总结

  • 低位优先字符串排序要求待排序的字符串长度一致
  • 低位优先字符串排序是稳定排序
  • 低位优先字符串排序的时间复杂度为O(WN),W表示字符串长度,N表示字符串个数
  • 低位优先字符串排序的空间复杂度为O(R+N)O(N)为辅助数组占用的空间,O(R)count[]数组占用的空间
0 0