【设计模式】16.行为型模式-策略(Strategy)

一、描述

  定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。

  1.角色

    (1)抽象类:定义算法方法。

    (2)具体实现类:继承抽象类,实现算法方法。

  2.类图

 

 

二、

以快速排序算法、合并排序算法为例,类图很简单,和上面的类图差不多,所以就不画了。直接上代码:

  1.抽象计算类

public interface Calculate {
    void order(int[] values);
}

  2.快速排序算法(想了解该算法的话参考我的文章:算法-快速排序

public class FastSortCalculate implements Calculate {
    @Override
    public void order(int[] values) {
        int left = 0;
        int right = values.length - 1;
        sort(values, left, right);
        System.out.println("快速排序:");
        for (int i = 0; i < values.length; i++) {
            System.out.print("  " + values[i]);
        }
        System.out.println();
    }

    private void sort(int[] a, int left, int right) {
        if (left > right) {
            return;
        }
        int i = left;
        int j = right;
        int sign = a[left];
        while (i != j) {
            //查找比sign小的元素位置
            while (a[j] >= sign && i < j) {
                j--;
            }
            //查找比sign大的元素位置
            while (a[i] <= sign && i < j) {
                i++;
            }
            //交换
            if (i < j) {
                int temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
        }
        //相遇或者遇到(8)(10)(11)等情况,直接交换
        a[left] = a[j];
        a[j] = sign;

        //分割数组重新排序
        sort(a, left, j - 1);
        sort(a, j + 1, right);
    }
}

  3.合并排序算法(想了解该算法的话参考我的文章:算法-合并排序

public class MergeSortCalculate implements Calculate {
    @Override
    public void order(int[] values) {
        //定义下标
        int right = values.length - 1;
        int left = 0;
        int[] b = new int[values.length];
        mergeSort(values, b, left, right);
        //合并
        System.out.println("合并排序:");
        for (int i = 0; i < b.length; i++) {
            System.out.print("  " + b[i]);
        }
        System.out.println();
    }

    public static void mergeSort(int[] a, int[] b, int left, int right) {
        if (left == right) {
            //分到最小单位
            return;
        }
        if (left < right) {
            //当未拆分完时继续拆分
            int mid = (left + right) / 2;
            //分组
            mergeSort(a, b, left, mid);
            mergeSort(a, b, mid + 1, right);

            //拆分完合并
            //i定义为左边数组起点
            int i = left;
            //i定义为右边数组起点
            int j = mid + 1;
            //新数组下标
            int t = 0;
            //当前两边数组未排序完成时
            while (i <= mid && j <= right) {
                //定义min接收较小数据
                int min;
                if (a[i] < a[j]) {
                    //若当前左边数组i位置上的数据小于右边数组j位置上的数据,说明右边数组j后面位置的数据都大于i对应的数据,
                    // 所以i++向后移动比较下一个左边数组的数据与当前右边数据j的数据。
                    min = a[i];
                    i++;
                } else {
                    //若左边数组i位置上的数据大于j位置上的数据,则i位置要继续与右边数组剩下的数据进行比较,j++
                    min = a[j];
                    j++;
                }
                //将较小数据放到b数组对应位置上,并且下标向后移动一位
                b[t++] = min;
            }

            //若左边数组上还有剩余数据,则放到数组中
            while (i <= mid) {
                b[t++] = a[i++];
            }
            //若右边数组上还有剩余数据,则放到数组中
            while (j <= right) {
                b[t++] = a[j++];
            }

            //将b数组中的有序数组放到a对应的位置上。
            t = 0;
            while (left <= right) {
                a[left++] = b[t++];
            }
        }
    }
}

  4.调用

public class Client {
    public static void main(String[] args) {
        int[] a = {9, 5, 2, 7, 12, 4, 3, 1, 11};
        Calculate fastSortCalculate = new FastSortCalculate();
        fastSortCalculate.order(a);

        Calculate mergeSortCalculate = new MergeSortCalculate();
        mergeSortCalculate.order(a);
    }
}

  5.效果

 

posted on 2022-06-28 15:49  技术猫猫  阅读(32)  评论(0编辑  收藏  举报

导航