策略模式 排序

定义:定义了算法家族,分别封装起来,让他们之间可以相互替换

类型:行为类模式

类图:


策略模式的结构

  • 封装类:也叫上下文,对策略进行二次封装,目的是避免高层模块对策略的直接调用。
  • 抽象策略:通常情况下为一个接口,当各个实现类中存在着重复的逻辑时,则使用抽象类来封装这部分公共的代码,此时,策略模式看上去更像是模版方法模式。
  • 具体策略:具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换。




抽象策略类:

public abstract class ISortService {
    public abstract void sort(int[] arr);
    public void  swap(int [] arr, int l,int r){
        int temp = arr[l];
        arr[l] = arr[r];
        arr[r] = temp;
    }
    public void show(int[] arr){
        System.out.println(Arrays.toString(arr));
    }
}

具体策略类:

冒泡排序:

public class BubbleSort  extends ISortService{

    @Override
    public void sort(int[] arr) {
        for(int i= arr.length-1;i>0;i--){
            for(int j=0;j<i;j++){
                if(arr[j] > arr[j+1]){
                    swap(arr,j,j+1);
                }
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = {2,4,1,6,3,8,7,9,5};
        ISortService bubbleSort = new BubbleSort();
        bubbleSort.show(arr);
        bubbleSort.sort(arr);
        bubbleSort.show(arr);
    }
}

插入排序

public class InsertSort extends ISortService {
    @Override
    public void sort(int[] arr) {
        for(int i=1;i<arr.length;i++){
            int temp = arr[i];
            int cursor = i;
            while (cursor > 0 && arr[cursor-1] > temp){
                arr[cursor] = arr[cursor-1];
                cursor --;
            }
            arr[cursor] = temp;
        }
    }

    public static void main(String[] args) {
        int[] arr = {2,4,1,6,3,8,7,9,5};
        ISortService sort = new InsertSort();
        sort.show(arr);
        sort.sort(arr);
        sort.show(arr);
    }
}

选择排序

public class SelectSort extends ISortService {
    @Override
    public void sort(int[] arr) {
        for (int i=0;i<arr.length;i++){
            int min = arr[i];
            int mPos = i;
            for (int j=i+1;j<arr.length;j++){
                if(arr[j] < min){
                    min = arr[j];
                    mPos = j;
                }
            }
            swap(arr,i,mPos);
        }

    }
    public static void main(String[] args) {
        int[] arr = {2,4,1,6,3,8,7,9,5};
        ISortService sort = new SelectSort();
        sort.show(arr);
        sort.sort(arr);
        sort.show(arr);
    }
}

归并排序:

public class MergSort  extends ISortService{

    public  void reMergSort(int [] arr,int l,int r){
        if(l == r){
            return;
        }
        int mid = (l+r)/2;
        reMergSort(arr,l,mid);
        reMergSort(arr,mid+1,r);
        merg(arr,l,mid,r);

    }
    public static void merg(int[] arr,int l,int m,int r){
        int [] temp = new int[r-l+1];
        int currentL = l,currentM = m+1;
        int k=0;
        while (currentL <= m && currentM<= r){
            if(arr[currentL] < arr[currentM]){
                temp[k++] = arr[currentL++];
            }else {
                temp[k++] = arr[currentM++];
            }
        }
        while (currentL <= m){
            temp[k++] = arr[currentL++];
        }
        while (currentM <= r){
            temp[k++] = arr[currentM++];
        }
        for(k=0;k<temp.length;k++){
            arr[l++] = temp[k];
        }
    }

    @Override
    public void sort(int[] arr) {
        reMergSort(arr,0,arr.length-1);
    }

    public static void main(String[] args) {
        int[] arr = {2,4,1,6,3,8,7,9,5};
        ISortService sort = new MergSort();
        sort.show(arr);
        sort.sort(arr);
        sort.show(arr);
    }
}

封装类:

public class SortUtil {
    ISortService sort;

    public ISortService getSort() {
        return sort;
    }

    public void setSort(ISortService sort) {
        this.sort = sort;
    }
    public void sort(int[] arr){
        sort.sort(arr);
    }
    public void show(int[] arr){
        sort.show(arr);
    }
}

测试类:

public class Client {
    public static void main(String[] args) throws Exception {
        int[] arr = getArr(150);
        saveToFile(arr,"old1.txt");
        List<ISortService> list = new ArrayList<>();
        list.add(new BubbleSort());
        list.add(new InsertSort());
        list.add(new SelectSort());
        list.add(new MergSort());
        long start, end;
        SortUtil sortUtil = new SortUtil();
        for (int i = 0; i < 4; i++) {
            int[] newArr = Arrays.copyOf(arr, arr.length);
            sortUtil.setSort(list.get(i));
            String fileName = list.get(i).getClass().getName();
//            sortUtil.show(newArr);
            start = System.currentTimeMillis();
            sortUtil.sort(newArr);
            end = System.currentTimeMillis();
            saveToFile(newArr,fileName+".txt");
            System.out.println( fileName+ "耗时: " + (end - start));
//            sortUtil.show(newArr);
            System.out.println("------------------------");
        }

    }

    public static int[] getArr(int size) {
        int[] arr = new int[size];
        for (int i = 0; i < size; i++) {
            arr[i] = (int) (Math.random() * size);
        }
        return arr;
    }

    public static void saveToFile(int[] arr, String fileName) throws Exception {
        File file = new File("D://test/" + fileName);
        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
        int i = 1;
        for (int num : arr) {

            if (i % 16 == 0) {
                bw.newLine();
                i = 1;
            }

            bw.write(num + "\t");
            i++;
        }
        bw.flush();
        bw.close();

    }
}



策略模式的优缺点

       策略模式的主要优点有:

  • 由于策略类实现自同一个抽象,所以他们之间可以自由切换。
  • 易于扩展,增加一个新的策略,可以在不修改原来代码上进行扩展。
  • 避免使用多重条件,如果不使用策略模式,对于所有的算法,必须使用条件语句进行连接,通过条件判断来决定使用哪一种算法

       策略模式的缺点主要有两个:

  • 维护各个策略类会给开发带来额外开销,可能大家在这方面都有经验:一般来说,策略类的数量超过5个,就比较令人头疼了。
  • 必须对客户端(调用者)暴露所有的策略类,因为使用哪种策略是由客户端来决定的,因此,客户端应该知道有什么策略,并且了解各种策略之间的区别,否则,后果很严重。


参考:

http://blog.csdn.net/zhengzhb/article/details/7609670



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值