第一期:直接选择排序
题目分析:
以从小到大排序为例进行分析。直接选择排序的思想是每遍历一遍,对所有元素进行两两比较并从中选出最小的一个数。将目前选出的最小值和最前面未排好序的元素进行交换。直到所有元素排序好。
示例:{4,2,1,9,8}
第一遍: 从第一个元素4开始,将4和剩余元素一一比较,选出最小元素为1,那么4和1进行交换,得到的序列为 {1,2,4,9,8}
第二遍: 从第二个元素2开始,将2和剩余元素一一比较(位置在2之前的元素不参与比较了,因为已经排好序了),其位置后面的元素都比2大,最小元素为自身,那么不用进行交换,得到的序列为 {1,2,4,9,8}
第三遍: 从第三个元素4开始,将4和剩余元素一一比较(位置在4之前的元素不参与比较了,因为已经排好序了),其位置后面的元素都比4大,最小元素为自身,那么不用进行交换,得到的序列为 {1,2,4,9,8}
第四遍: 从第四个元素9开始,将9和剩余元素一一比较(位置在9之前的元素不参与比较了,因为已经排好序了),选出最小元素为8,那么9和8进行交换,得到的序列为 {1,2,4,8,9}
第五遍: 从第五个元素9开始,将9和剩余元素一一比较,发现剩余元素没有了,位置都在9之前,说明已经全部排序好了。最终序列为 {1,2,4,8,9}
Java代码:
public class Sort{
public static void main(String[] args){
// 将所有任务交由selectSort方法处理
selectSort();
}
private static void selectSort(){
// 直接给定一个乱序数组
int[] array = {4,2,1,9,8};
// 外循环,控制待比较的第一个元素
for(int i=0;i<arrar.length;i++){
// 为了找到遍历一次的最小值,我们借助其索引值
// 首先,我们假设最小值为数组的第一个元素
int minIndex = i;
// 内循环,控制待比较的第二个元素
for(int j=(i+1); j<arrar.length;j++){
// 判断大小
if(array[j]<array[minIndex]){
// 记录下当前较小值的索引
minIndex = j;
}
}
// 如果最小值所对应的索引发生更改后,我们需要进行交换操作。
if(minIndex != i){
array[minIndex] = array[minIndex] ^ array[i];
array[i] = array[minIndex] ^ array[i];
array[minIndex] = array[minIndex] ^ array[i];
}
}
// 到此为止,排序任务完成,需要打印数组进行验证结果
for(int i=0; i<array.length;i++){
// 最后一个元素需要换行
if(i==array.length-1){
System.out.println(array[i]);
}else{
System.out.print(array[i]+" ");
}
}
}
}
简要分析:
时间复杂度分析(最好、最坏和平均情况): 选择排序无论何种情况每个大循环内都需要比较未排序部分找出最小元素的坐标,所以时间复杂度都为O(n²)。
空间复杂度分析: 因为是在自身数组上进行排序,无需申请额外的内存空间,所以空间复杂度为O(1),是原地排序算法
稳定性分析:不稳定
小技巧:
交换两个整型数据a和b:
// 方法一:利用中间变量,需要额外的内存
int temp = a;
a = b;
b = temp;
// 方法二:不利用中间变量
a = a+b;
b = a-b;
a = a-b;
// 方法三:对方法二的改进,效率更高(计算机最喜欢逻辑操作)。
a = a ^ b;
b = a ^ b;
a = a ^ b;