字符串--字符串排序

键索引计数法


  1. 频率统计
  2. 将频率转换为索引
  3. 数据分类
  4. 回写

频率统计:统计每个字符出现的次数
将频率转换为索引:确定不同字符首位置

低位优先的字符串排序

从右到左检查检查键中的字符

public class LSD {
    public static void sort(String[] a, int w){
        int n = a.length;
        int R = 256;
        String[] aux = new String[n];

        for(int d=w-1; d>=0; d--){                      //根据第d个字符用键索引计数法排序
            int[] count = new int[R+1];                 //计算出现频率                                    
            for(int i=0; i<n; i++)                      
                count[a[i].charAt(d)+1]++;

            for(int r=0; r<R; r++)                     //将频率转换为索引
                count[r+1] += count[r];

            for(int i=0; i<n; i++)                     //将元素分类                      
                aux[count[a[i].charAt(i)]++] = a[i];

            for(int i=0; i<n; i++)                     //回写
                a[i] = aux[i];
        }
    }
}

  • 高位优先的字符串排序

    从左到右检查键中的字符,使用递归算法和键索引计数法

public class MSD {
    private static int R = 256;         //基数
    private static final int M = 15;    //小数组的切换阈值
    private static String[] aux;        //数据分类的辅助数组

    private static int charAt(String s, int d){
        if(d<s.length()) return s.charAt(d);
        else return -1;
    }

    public static void sort(String[] a){
        int n = a.length;
        aux = new String[n];
        sort(a,0,n-1,0);
    }

    private static void sort(String[] a, int lo, int hi, int d){
        if(hi <= lo+M){
            Insertion.sort(a, lo, hi, d);        //小数组(小于等于M个字符串)使用插入排序,提高性能
            return;
        }

        int[] count = new int[R+2];
        for(int i=lo; i<=hi; i++)                       
            count[charAt(a[i], d) + 2]++;

        for(int r=0; r<R; r++)                     //将频率转换为索引
            count[r+1] += count[r];

        for(int i=lo; i<=hi; i++)                      //将元素分类                      
            aux[count[charAt(a[i], d) + 1]++] = a[i];

        for(int i=lo; i<=hi; i++)                     //回写
            a[i] = aux[i-lo];

        for(int r=0; r<R; r++)
            sort(a, lo+count[r], lo+count[r+1]-1, d+1);  //递归
    }

}

三向字符串快速排序

根据键的首字母进行三向切分,仅在中间子数组的下一个字符(因为键的首字母都与切分字符相等)继续递归排序.

public class Quick3string {
    private static int charAt(String s, int d){
        if(d<s.length()) return s.charAt(d);
        else return -1;
    }

    public static void sort(String[] a){
        sort(a, 0, a.length, 0);
    }

    private static void sort(String[] a, int lo, int hi, int d){
        if(hi<=lo) return;
        int lt = lo, gt = hi;
        int v = charAt(a[lo], d);
        int i = lo+1;
        while(i <= gt){
            int t = charAt(a[i], d);
            if      (t<v) exch(a, lt++, i++);    //和低位交换位置
            else if (t>v) exch(a, i, gt--);      //和高位交换位置
            else     i++;
        }

        sort(a, lo, lt-1, d);           //三部分中的上半部分(小)
        if(v>0) sort(a, lt, gt, d+1);   //三部分中的中间部分
        sort(a, gt+1, hi, d);           //三部分中的下半部分(大)
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值