`
xiaqi.2009
  • 浏览: 873 次
  • 性别: Icon_minigender_1
  • 来自: 西安
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

简单工厂模式和策略模式实现简单排序算法。

阅读更多
第一次使用设计模式编写java版的排序算法。欢迎指点,有不足之处还望不吝赐教。
本人略懒,UML图就不画了。

================Sort类,所有将要实现的算法的母类=====================
package sort;

import java.util.Calendar;
import java.util.Random;

public abstract class Sort {

    // 存储排序数量的数组。
    int[] arrays;

    // 指定随机生成的数字的范围。
    int range;

    // 存储对应排序数量所用的时间。
    long[] sortTimes;

    Sort(){
        
    }
    
    Sort(int[] arrays, int range){
        this.arrays = arrays;
        this.range = range;
        this.sortTimes = new long[arrays.length];
    }
    
    // 具体排序方法。
    public abstract int[] sort(int[] array, int length);
    
    // 显示结果 。
    public void display(String name) {
        System.out.println("排序数量\t\t" + name + "(ms)");
        for (int n = 0; n < arrays.length; n++) {
            int turns = 10; // 排十次,求平均。
            long time = 0;
            for (int j = 0; j < turns; ++j) {
                long begin = Calendar.getInstance().getTimeInMillis();
                this.sort(this.getRandArray(arrays[n]), arrays[n]);
                long end = Calendar.getInstance().getTimeInMillis();
                time += (end - begin);
            }
            sortTimes[n] = time / turns;
        }
        for (int i = 0; i < arrays.length; ++i) {
            System.out.println("" + arrays[i] + "\t\t" + sortTimes[i]);
        }
    }

    // 生成指定长度的数组。
    public int[] getRandArray(int n) {
        int[] array = new int[n];
        Random rand = new Random();
        for (int i = 0; i < array.length; i++) {
            array[i] = rand.nextInt(range);
        }
        return array;
    }

    // 测试数组是否排序成功,顺序由小到大。
    public boolean isSorted(int[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            if (array[i] > array[i + 1]) {
                return false;
            }
        }
        return true;
    }
    
    //显示数组
    public void display(int[] array){
        for(int i = 0; i < array.length; i++){
            System.out.print(array[i] + " ");
        }
    }
}


=================================工厂类==============================
package sort;

public class SortFactory {

    public static Sort creatSort(String sortName, int[] arrays, int range) {
        Sort sort = null;
        char[] sortname = sortName.toCharArray();
        // jdk 1.7过后switch就支持String类型了。
        switch (sortname[0]) {
        case 'B': // 冒泡排序
            sort = new BubbleSort(arrays, range);
            break;
        case 'S': // 选择排序
            sort = new SelectSort(arrays, range);
            break;
        case 'I': // 插入排序
            sort = new InsertSort(arrays, range);
            break;
        case 'M': // 归并排序
            sort = new MergeSort(arrays, range);
            break;
//        case 'S': // 系统排序
//            sort = new SystemSort(arrays, range);
//            break;
        case 'H': // 堆排序
            sort = new HeapSort(arrays, range);
            break;
        }
        return sort;
    }
}

===============================测试类================================
// 其中插入排序和系统排序是策略模式实现。

package sort;

import org.junit.Test;

public class SortTest {

	// 存储排序数量的数组。
	int[] arrays = { 1000, 2000, 5000, 10000, 20000, 50000, 100000 };

	// 指定随机生成的数字的范围(0-1000)。
	int range = 1000;

	// 使用简单工厂创建具体排序类。
	Sort sort = null;

	// 使用策略模式实现,适用于调用的方法都是做的相同的工作,只是实现不同。
	SortContext sortContext;

	// 冒泡排序,使用简单工厂实现。用户需要知道工厂类和Sort接口。
	@Test
	public void testBubbleSort() {
		sort = SortFactory.creatSort("BubbleSort", arrays, range);
		sort.display("冒泡排序");
	}

	// 选择排序。
	@Test
	public void testSelectSort() {
		sort = SortFactory.creatSort("SelectSort", arrays, range);
		sort.display("选择排序");
	}

	// 归并排序。
	@Test
	public void testMergeSort() {
		sort = SortFactory.creatSort("MergeSort", arrays, range);
		sort.display("归并排序");
	}

	// 堆排序。
	@Test
	public void testHeapSort() {
		sort = SortFactory.creatSort("HeapSort", arrays, range);
		sort.display("堆排序");
	}

	// 插入排序。
	// 使用简单工厂加策略模式实现。用户只需知道SortContext,进一步降低耦合性。
	@Test
	public void testInsertSort() {
		sortContext = new SortContext("InsertSort", arrays, range);
		sortContext.display("插入排序 ");
	}

	// 系统排序,快速排序。
	@Test
	public void testSystemSort() {
		sortContext = new SortContext("SystemSort", arrays, range);
		sortContext.display("系统排序");
	}

}

================================策略模式=======================================
package sort;

public class SortContext {

	Sort sort = null;

	// 简单工厂实现具体策略。
	public SortContext(String sortName, int[] arrays, int range) {
		char[] sortname = sortName.toCharArray();
		// jdk 1.7过后switch就支持String类型了。
		switch (sortname[0]) {
		case 'B': // 冒泡排序
			sort = new BubbleSort(arrays, range);
			break;
		case 'I': // 插入排序
			sort = new InsertSort(arrays, range);
			break;
		case 'M': // 归并排序
			sort = new MergeSort(arrays, range);
			break;
		case 'S': // 系统排序
			sort = new SystemSort(arrays, range);
			break;
		case 'H': // 堆排序
			sort = new HeapSort(arrays, range);
			break;
		}
	}

	// 策略模式,封装公共的功能。
	public void display(String name) {
		sort.display(name);
	}
}

===============================冒泡排序========================================
package sort;

public class BubbleSort extends Sort {

	BubbleSort(int[] arrays, int range) {
		super(arrays, range);
		// TODO Auto-generated constructor stub
	}

	public BubbleSort() {
		// TODO Auto-generated constructor stub
	}

	// 冒泡。
	@Override
	public int[] sort(int[] array, int length) {
		int temp;
		for (int out = 0; out < length; out++)
			for (int in = length - 1; in > out; in--)
				if (array[in] < array[in - 1]) {
					temp = array[in];
					array[in] = array[in - 1];
					array[in - 1] = temp;
				}
		return array;
	}
}


=================================选择排序======================================
package sort;

public class SelectSort extends Sort {

	SelectSort() {

	}

	SelectSort(int[] arrays, int range) {
		super(arrays, range);
	}

	// 选择排序,从小到大。
	@Override
	public int[] sort(int[] array, int length) {
		// TODO Auto-generated method stub
		int left, right, min, temp;
		for (left = 0; left < length - 1; left++) {
			min = left;
			for (right = left + 1; right < length; right++) {
				if (array[right] < array[min])
					min = right;
			}
			temp = array[left];
			array[left] = array[min];
			array[min] = temp;
		}
		return array;
	}

}

=====================================插入排序==================================
package sort;

public class InsertSort extends Sort {

	public InsertSort() {
		// TODO Auto-generated constructor stub
	}

	InsertSort(int[] arrays, int range) {
		super(arrays, range);
		// TODO Auto-generated constructor stub
	}

	// 插入。
	@Override
	public int[] sort(int[] array, int length) {
		int left, right, temp;

		for (right = 1; right < length; right++) {
			temp = array[right];
			left = right - 1;
			while (left >= 0 && (temp < array[left])) {
				array[left + 1] = array[left];
				left--;
			}
			array[left + 1] = temp;
		}
		return array;
	}
}


=================================归并排序======================================
package sort;

import java.util.Arrays;

public class MergeSort extends Sort {

	public MergeSort() {
		// TODO Auto-generated constructor stub
	}

	MergeSort(int[] arrays, int range) {
		super(arrays, range);
		// TODO Auto-generated constructor stub
	}

	@Override
	public int[] sort(int[] array, int length) {
		// TODO Auto-generated method stub
		if (length == 0 || length == 1) {
			return null;
		}

		int mid = length / 2;
		int[] a = Arrays.copyOfRange(array, 0, mid);
		int[] b = Arrays.copyOfRange(array, mid, array.length);

		sort(a, a.length);
		sort(b, b.length);

		merge(a, b, array);
		return array;
	}

	private void merge(int[] a, int[] b, int[] ary) {
		int i = 0;
		int j = 0;
		int k = 0;
		while (i < a.length && j < b.length) {
			if (a[i] <= b[j]) {
				ary[k++] = a[i++];
			} else {
				ary[k++] = b[j++];
			}
		}

		for (; i < a.length; ++i) {
			ary[k++] = a[i];
		}
		for (; j < b.length; ++j) {
			ary[k++] = b[j];
		}
	}

}


======================================堆排序===================================
package sort;

public class HeapSort extends Sort {

	HeapSort() {

	}

	HeapSort(int[] arrays, int range) {
		super(arrays, range);
		// TODO Auto-generated constructor stub
	}

	@Override
	public int[] sort(int[] array, int length) {
		// TODO Auto-generated method stub
		buildHeap(array); // 首先,建一个堆, 此时a[0] 就是最大的元素
		for (int i = length - 1; i > 0; i--) { // 选出最大的元素
			swap(array, 0, i); // 在这之后, i 以及后面的元素都是有序的
			heapify(array, 0, i - 1); // 根元素由于被交换过,所以需要进行一次调整,让他再变成堆。
		}
		return array;
	}

	void buildHeap(int[] array) {
		int n = array.length;
		for (int i = n / 2 - 1; i >= 0; --i) { // n / 2 - 1, 就是最后一个有子节点的元素
			heapify(array, i, n - 1);
		}
	}

	// 判断是否为大顶堆。
	boolean isHeap(int[] a, int i) {
		int n = a.length;
		if (i >= n) {
			return true;
		}
		int left = 2 * i + 1; // 左节点
		int right = 2 * i + 2; // 右节点
		if (left < n && a[left] > a[i]) {
			return false;
		}

		if (right < n && a[right] > a[i]) {
			return false;
		}

		return isHeap(a, left) && isHeap(a, right); // 左右子树也是大顶堆。
	}

	// 不断调整,直到整个数组变成堆。
	// i的左右子树都是堆 (j后面的元素不管,不属于堆), 我们要把他调整成堆。
	void heapify(int[] a, int i, int j) {
		int left = i * 2 + 1;
		int right = i * 2 + 2;
		if (left > j) { // 没有左子树
			return;
		}

		int large = left;
		if (right <= j && a[left] < a[right]) {
			large = right;
		}

		if (a[i] < a[large]) { // 如果根元素比 large小,重新调整。
			swap(a, i, large);
			heapify(a, large, j); // 继续操作large子树。
		}
	}

	private void swap(int[] a, int i, int j) {
		int t = a[i];
		a[i] = a[j];
		a[j] = t;
	}
}


===================================系统排序====================================
package sort;

import java.util.Arrays;

public class SystemSort extends Sort {

	public SystemSort() {
		// TODO Auto-generated constructor stub
	}

	SystemSort(int[] arrays, int range) {
		super(arrays, range);
		// TODO Auto-generated constructor stub
	}

	@Override
	public int[] sort(int[] array, int length) {
		// TODO Auto-generated method stub
		Arrays.sort(array);
		return array;
	}

}

分享到:
评论

相关推荐

    各种设计模式及解析

    2、策略模式 Strategy (用户选择各种排序方法进行排序) 3、简单工厂 Simple Factory (很多的产品,由一个工厂出产) 4、抽象工厂 Abstract Factory (很多的产品,分别由不同的工厂出产) 5、模板方法 Template ...

    招银网络java科技笔试题-WaytoInterview:JVM和设计模式和算法的快速浏览

    常用排序算法 Leetcode IsomorphicStrings_lc205 lowestCommonAncestor_lc235 Netease 2018 - 2019 年度网易Android、Java岗算法题目汇总 最大兴趣值(MaxInterest) 数塔问题(BalancedTower) 丰收(Harvest) 牛牛找...

    传智播客扫地僧视频讲义源码

    本教程共分为5个部分,第一部分是C语言提高部分,第二部分为C++基础部分,第三部分为C++进阶部分,第四部分为C、C++及数据结构基础部分,第五部分为C_C++与设计模式基础,内容非常详细. 第一部分 C语言提高部分目录...

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    抽象工厂模式 工厂方法模式 建造这模式 原型模式 单例模式 行为模式 责任链模式 命令模式 解释器模式 迭代器模式 中介者模式 备忘录模式 观察者模式 状态模式 策略模式 模板方法模式 访问者模式 ...

    Learning:我的学习

    8种基本排序算法; 多线程的一些简单模拟; Java基础知识的学习 内部类 Java 虚拟机的学习; JVM 与 Java 概述; JVM 架构模型与生命周期; 类加载子系统; 运行时数据区; 栈 堆 方法区 设计模式; 单例模式 观察者...

    asp.net知识库

    利用反射实现ASP.NET控件和数据实体之间的双向绑定,并且在客户端自动验证输入的内容是否合法 asp.net报表解决方法 SQLDMO类的使用 SQL过程自动C#封装,支持从表到基本存储过程生成 使用SQLDMO控制 SQL Server 使用SQL...

    java 面试题 总结

    Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。 10、&和&&的区别。 &是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。 11、HashMap...

    超级有影响力霸气的Java面试题大全文档

    Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。 13、&和&&的区别。 &是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。 14、...

    编程新手真言......

    第四部分 一个例子:游戏引擎和实现 206 第12章 设计(需求分析) 207 12.1 第一天:接到一个案子 207 12.2 第二天:需求分析 208 第13章 设计(领域分析与抽象) 210 13.1 原语设计 210 13.2 了解Yake 216 13.3 ...

    php网络开发完全手册

    5.7.1 策略模式(Strategy Pattern) 81 5.7.2 单例模式(Singleton Pattern) 81 5.7.3 工厂模式(Factory Pattern) 83 5.8 接口与抽象类 86 5.8.1 接口的定义 86 5.8.2 单一接口的实现 87 5.8.3 多重接口的实现 ...

    Java并发编程实战

    如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的...

    NHibernate参考文档 2.0.0 chm

    4.3. 实现 Equals() 和 GetHashCode() 方法 4.4. 持久化生命周期(Lifecycle)中的回调(Callbacks) 4.5. 合法性验证(IValidatable)回调 5. 对象/关系数据库映射基础(Basic O/R Mapping) 5.1. 映射定义(Mapping...

    java8集合源码分析-The-Road-To-Bald-Man:Java技能加点,秃顶之路

    二、数据结构和算法 数据结构 字符串 数组 链表 二叉树 堆、栈、队列 哈希 算法 查找 排序 贪心 分治 动态规划 回溯 三、计算机网络 ARP协议 IP/ICMP协议 TCP/UDP协议 DNS/HTTP/HTTPS协议 Session/Cookie 四、数据库...

    NHibernate中文帮组文档(2008.11月更新)

    4.3. 实现 Equals() 和 GetHashCode() 方法 4.4. 持久化生命周期(Lifecycle)中的回调(Callbacks) 4.5. 合法性验证(IValidatable)回调 5. 对象/关系数据库映射基础(Basic O/R Mapping) 5.1. 映射定义(Mapping...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例173 实现复选框中的全选、反选和不选 208 实例174 隐藏域提交用户的ID值 210 实例175 图像域替代提交按钮 211 实例176 跳转菜单实现页面跳转 213 实例177 上传图片预览 214 实例178 去掉下拉选项的边框 215 实例...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例173 实现复选框中的全选、反选和不选 208 实例174 隐藏域提交用户的ID值 210 实例175 图像域替代提交按钮 211 实例176 跳转菜单实现页面跳转 213 实例177 上传图片预览 214 实例178 去掉下拉选项的边框 215 实例...

    Java学习笔记-个人整理的

    {1.11.2}排序算法}{38}{subsection.1.11.2} {1.11.2.1}选择排序}{38}{subsubsection.1.11.2.1} {1.11.2.2}冒泡排序}{39}{subsubsection.1.11.2.2} {1.11.2.3}插入排序}{40}{subsubsection.1.11.2.3} {1.11.3}...

Global site tag (gtag.js) - Google Analytics