前言
冒泡排序算法中的缺点:在两个数之间比较会进行多次交换位置才能得出最终结果。就比如第一个数A与第二个数B比较,只要A比B大就会进行交换,但不能确定的是否是最小的元素。
1.基本思想
而选择排序则可以避免这种耗时间的交换操作,从第一个元素开始,扫描整个待排序数组,找到最小元素之后再与第一个元素进行交换,然后再从第二个元素开始,继续寻找最小的元素与第二个元素进行交换位置,以此类推。
2.实例
public class Sort {
private int[] array;
public Sort(int[] array) {
this.array = array;
}
//排序打印格式
public void display(){
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]+"\t");
}
System.out.println();
}
public void selectionSort(){
int minPoint;//最小元素
int len = array.length;
int temp;
int counter = 1;
for (int i = 0; i <len-1 ; i++) {
minPoint = i;
// 每完成一轮排序,就确定了一个相对最小元素,下一轮排序只对后面的元素排序
for (int j = i+1; j <= len-1; j++) {
// 如果待排数组中的某个元素比当前元素小,minPoint指向该元素的下标
if (array[j] < array[minPoint]){
minPoint = j;
}
}
// 如果发现了更小的元素,交换位置
if (minPoint != i){
temp = array[i];
array[i] = array[minPoint];
array[minPoint] = temp;
}
System.out.print("第" + counter + "轮排序结果:");
display();
counter++;
}
}
//测试方法
public static void main(String[] args) {
int[] a = {20,10,40,30,60,50};
Sort sort = new Sort(a);
System.out.print("未排序时的结果:");
sort.display();
sort.selectionSort();
}
}
3.结果打印:
4.算法的分析
选择排序和冒泡排序都需要进行N*(N-1)/2次比较,但是只需要N次交换,当N很大时,交换次数的时间影响力更大,所以选择排序的时间复杂度为O(N^2)。
选择排序的的效率是比冒泡排序算法的效率要高的.
5.改进代码
传统的选择排序每次只确定最小值,根据改进冒泡算法的经验,我们可以对排序算法进行如下改进:每趟排序确定两个最值——最大值与最小值,这样就可以将排序趟数缩减一半。代码如下:
public void selectionSort_improvement(){
int minPoint;//最小元素
int maxPoint;//最大元素
int len = array.length;
int temp;
int counter = 1;
for (int i = 0; i <len/2 ; i++) {
minPoint = i;
maxPoint = i;
// 每完成一轮排序,就确定了两个最值,下一轮排序时比较范围减少两个元素
for (int j = i+1; j <= len-1-i; j++) {
if (array[j] < array[minPoint]){
minPoint = j;
}
else if (array[j] > array[maxPoint]) {
maxPoint = j;
}
}
if (minPoint != i){
temp = array[i];
array[i] = array[minPoint];
array[minPoint] = temp;
// 原来的第一个元素已经与下标为minPoint的元素交换了位置
// 如果之前maxPoint指向的是第一个元素,那么需要将maxPoint重新指向array[minPoint]
// 因为现在array[minPoint]存放的才是之前第一个元素中的数据
if (maxPoint == i){
maxPoint = minPoint;
}
}
if (maxPoint != len-1-i){
temp = array[len - 1 - i];
array[len - 1 - i] = array[maxPoint];
array[maxPoint] = temp;
}
System.out.print("第" + counter + "轮排序结果:");
display();
counter++;
}
}
结果如下: