内排序:数据是放在内存中处理,排序时不涉及数据的内、外存交换,则称之为内排序。
直接选择排序的基本思想是:假定需要给n个数据元素排序,0≤i≤n-1.数据元素的序号从0到n-1.第i趟排序开始时,当前有序区为第0个元素到第i-1个元素,无序区为第i个元素到第n-1个元素。该趟排序则是从当前无序区中选出最小的数据元素,假定为第k个,将它与无序区的第一个元素互换,使得有序区变为第0个到第i个,无序区变为第i+1个到第n-1个。因为每趟排序均使有序区中增加了一个数据元素,且有序区中的数据元素均不大于无序区中的数据元素,所以进行n-1趟排序之后,有序区变为从第0个到第n-2个,无序区就剩下最后一个元素(第n-1个元素)。也就是说,经过n-1趟排序之后,这n个数据元素已经按照递增排列。
下面以一个类型为自定义的日期类型的数组的排序为例,演示直接选择排序算法。
public class TestDate{
public static void main(String[] args){
//动态初始化数组
MyDate[] dates=new MyDate[5];
//为数组赋值
dates[0]=new MyDate(2007,8,20);
dates[1]=new MyDate(2007,3,12);
dates[2]=new MyDate(2005,10,25);
dates[3]=new MyDate(2004,6,28);
dates[4]=new MyDate(2009,9,1);
//打印数组的原始顺序
System.out.println("原始顺序为");
print(dates);
System.out.println("");
//进行直接选择排序
selectSort(dates);
}
//直接选择排序的方法
public static void selectSort(MyDate[] dates){
//循环计数
int i,j;
//存放每趟循环最小数据元素的下标
int k;
//中间变量
MyDate temp;
int len=dates.length;
//做第i趟排序
for(i=0;i<len;i++){
k=i;
//当前无序区[i...n-1]中选最小的数据元素,其下标为k
for(j=i+1;j<len;j++){
if(dates[k].compare(dates[j])>0){
k=j;
}
}
//最小元素与该无序区第一个元素进行交换
if(k!=i){
temp=dates[i];
dates[i]=dates[k];
dates[k]=temp;
}
System.out.println("第"+i+"趟排序之后的顺序:");
print(dates);
System.out.println("");
}
}
//打印方法
public static void print(MyDate[] dates){
for(MyDate mydate : dates){
System.out.println(mydate);
}
}
}
//自定义的日期类
class MyDate{
int year;
int month;
int day;
MyDate(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
}
//比较方法
public int compare(MyDate mydate){
return year>mydate.year ? 1
:year<mydate.year ? -1
:month>mydate.month ? 1
:month<mydate.month ? -1
:day>mydate.day ? 1
:day<mydate.day ? -1 : 0 ;
}
//重写了toString方法,方便用System.out.println直接打印输出
public String toString(){
return "yeae-month-day: "+year+"-"+month+"-"+day;
}
}
执行结果如下:
原始顺序为
yeae-month-day: 2007-8-20
yeae-month-day: 2007-3-12
yeae-month-day: 2005-10-25
yeae-month-day: 2004-6-28
yeae-month-day: 2009-9-1
第0趟排序之后的顺序:
yeae-month-day: 2004-6-28
yeae-month-day: 2007-3-12
yeae-month-day: 2005-10-25
yeae-month-day: 2007-8-20
yeae-month-day: 2009-9-1
第1趟排序之后的顺序:
yeae-month-day: 2004-6-28
yeae-month-day: 2005-10-25
yeae-month-day: 2007-3-12
yeae-month-day: 2007-8-20
yeae-month-day: 2009-9-1
第2趟排序之后的顺序:
yeae-month-day: 2004-6-28
yeae-month-day: 2005-10-25
yeae-month-day: 2007-3-12
yeae-month-day: 2007-8-20
yeae-month-day: 2009-9-1
第3趟排序之后的顺序:
yeae-month-day: 2004-6-28
yeae-month-day: 2005-10-25
yeae-month-day: 2007-3-12
yeae-month-day: 2007-8-20
yeae-month-day: 2009-9-1
第4趟排序之后的顺序:
yeae-month-day: 2004-6-28
yeae-month-day: 2005-10-25
yeae-month-day: 2007-3-12
yeae-month-day: 2007-8-20
yeae-month-day: 2009-9-1