进来学习了设计模式,这里使用策略模式来组织多种排序算法。
首先我们定义一个抽象类,OrderBase,数据的输入,展示部分在抽象类里实现,具体的排序逻辑在各个子类里实现。
为什么用抽象类不用接口?接口里只有函数的定义,不能有实现。使用抽象类,可以实现公共函数,定义抽象函数。(父类和子类就是一个从一般到特殊的过程)
OrderBase.java
public abstract class OrderBase {
public int []data;
public static final int NUM_SIZE = 10;
public OrderBase(int num[])
{
data = new int [10];
for(int i=0;i<data.length;i++)
{
data[i]=num[i];
}
}
public void showData()
{
System.out.println("data ");
for(int i=0;i<data.length;i++)
{
System.out.print(" "+data[i]);
}
System.out.println(" ");
}
public abstract void Order();
}
接下来是快速排序的实现。快速排序的思想是把一组数据中的一个数据作为“基准”数,比基准数大的放在“基准”的右边,比基准数小的放在“基准”的左边(由小到大排列)。分而治之,层层递归。
如何实现比基准数大的放在“基准”的右边,比基准数小的放在“基准”的左边?
我们把每一组数据最左边的数据设为“基准”;然后引入两个哨兵,一个为i,站在数组的最左侧,一个为j,站在最右侧,每次j先移动,找到比基准小的数,之后i移动,找到比基准大的数,交换两个哨兵指向的数据,之后两个哨兵继续移动,依旧是j先移动,i后移动,直到i和j指向同一个数据(i==j)
public class QuickSort extends OrderBase {
public QuickSort(int[] num) {
super(num);
// TODO Auto-generated constructor stub
}
@Override
public void Order() {
Quick(0,data.length-1);
// TODO Auto-generated method stub
}
public void Quick(int left,int right)
{
int i=left,j=right;
if(i>=j)
return;
int temp = data[left];
while(i!=j)
{
while(data[j]>temp&&j>i)
{
j--;
}
while(data[i]<=temp&&j>i)
{
i++;
}
int t = data[i];
data[i]=data[j];
data[j]=t;
}
data[left]=data[i];
data[i]=temp;
Quick(i+1,right);
Quick(left,i-1);
}
}
之后是冒泡排序和桶排序,代码分别是BubbleSort.java和bucket.java
public class bucket extends OrderBase {
private int book[];
public bucket(int[] num) {
super(num);
// TODO Auto-generated constructor stub
}
@Override
public void Order() {
book = new int[100];
int count=0;
for(int i=0;i<data.length;i++)
{
book[data[i]]++;
}
for(int i =0;i< book.length;i++)
{
int n = book[i];
while(n>0)
{
data[count++]=i;
n--;
}
}
// TODO Auto-generated method stub
}
}
public class BubbleSort extends OrderBase {
public BubbleSort(int[] num) {
super(num);
// TODO Auto-generated constructor stub
}
public void Order()
{
for(int i=0;i<data.length;i++)
{
for(int j=0;j<data.length-1-i;j++)
{
if(data[j]>data[j+1])
{
int temp =data[j];
data[j]=data[j+1];
data[j+1]=temp;
}
}
}
}
}
现在我们开始涉及到策略模式。我们创建一个类似于装载策略的“锦囊类”,Context,这个类的成员对象就是之前我们定义的抽象类OrderBase,根据传入的子类的类型,分别调用不同的排序函数。(个人感觉多态就是设计模式的基石)。代码Context.java 如下。
public class Context {
private OrderBase orderbase;
public Context(OrderBase orderbase)
{
this.orderbase = orderbase;
}
public void show()
{
orderbase.showData();
}
public void Order()
{
orderbase.Order();
}
}
用户就可以用Context类作为入口,使用排序算法。
import java.util.Random;
public class Test {
protected static int num[] = new int[10];
public static void main(String[] args) {
CreateRandomNum();
Context context = new Context(new QuickSort(num));
context.show();
context.Order();
context.show();
// TODO Auto-generated method stub
}
public static void CreateRandomNum()
{
long t =System.currentTimeMillis();
Random rand = new Random(t);
for(int i=0;i<num.length;i++)
{
num[i]=rand.nextInt(100)+1;
}
}
}
这样的代码扩展性很好,假设我们要加入选择排序的算法,我们可以创建一个OrderBase的子类InsertSort,重写真正的排序函数Order,调用时只需要从主函数修改一个单词就好了。