选择排序–简单选择排序的改进(二元选择排序)
改进并没有降低时间复杂度和空间复杂度。但是却提供了一个很好的思路:类似与多线程解决问题的方法。在每次循环时找到一个最小值和最大值分别放到对应的位置有序位置上,两边同时排序。这样可以把最外层的循环由n降至n/2。
这种方法在提高效率的同时,也带来了一些问题:就像多线程一下,如果同时访问一个位置数据可能就会出现问题
public class SelectSort { public static void main(String[] args) { int arr[] = { 8, 6, 2, 3, 1, 5, 7, 4 }; selectionSort(arr); for (int i : arr) { System.out.println(i); } } public static void selectionSort(int arr[]) { int length = arr.length; for (int i = 0; i < length / 2; i++) { // 遍历整个数组 int minIndex = i; // 声明最小值坐标 int maxIndex = i; // 声明最大值坐标 for (int j = i + 1; j < length; j++) { // 遍历为交换的数组 if (arr[minIndex] > arr[j]) { // 拿当前最小值跟为交换的数组对比 minIndex = j; } if (arr[maxIndex] < arr[length-j]) { // 拿当前最大值跟为交换的数组对比 因为最大的数字已经确定,所以这里只对比没有确定的值。 maxIndex = length-j; } } int tmp = arr[i]; // 理论上最多是有三个数字进行交换。所以多声明一个变量 if (tmp == arr[maxIndex]&&i<length/2-1) { // 当前值为最大值 应该是先交换最大值,再交互那最小值 int maxTmp = arr[length - i - 1]; arr[length - i - 1] = arr[maxIndex]; arr[i] = maxTmp; // 把最大值赋值给 当前坐标的值 int minTmp=arr[i]; arr[i] = arr[minIndex]; // 把最小值赋值给 当前坐标的值 arr[minIndex]=minTmp; }else{ int maxTmp = arr[length - i - 1]; int minTmp=arr[minIndex]; arr[length - i - 1] = arr[maxIndex]; arr[maxIndex] = maxTmp; // 把最大值赋值给 当前坐标的值 arr[minIndex]=tmp; arr[i]=minTmp; } } } }算法缺陷很明显:当排序的数组长度不是偶数的时候就会出现bug。所以这里改进一下,如果是奇数的话,外圈多循环一次就OK了。 public class SelectSort { public static void main(String[] args) { int arr[] = { 8, 6, 2, 3, 1, 5, 7, 4,9}; selectionSort(arr); for (int i : arr) { System.out.println(i); } } public static void selectionSort(int arr[]) { int length = arr.length; int forNum=(int) Math.ceil((double)arr.length/2); for (int i = 0; i < forNum; i++) { // 遍历整个数组 int minIndex = i; // 声明最小值坐标 int maxIndex = i; // 声明最大值坐标 for (int j = i + 1; j < length; j++) { // 遍历为交换的数组 if (arr[minIndex] > arr[j]) { // 拿当前最小值跟为交换的数组对比 minIndex = j; } if (arr[maxIndex] < arr[length-j]) { // 拿当前最大值跟为交换的数组对比 因为最大的数字已经确定,所以这里只对比没有确定的值。 maxIndex = length-j; } } int tmp = arr[i]; // 理论上最多是有三个数字进行交换。所以多声明一个变量 if (tmp == arr[maxIndex]&&i<forNum-1) { // 当前值为最大值 应该是先交换最大值,再交互那最小值 int maxTmp = arr[length - i - 1]; arr[length - i - 1] = arr[maxIndex]; arr[i] = maxTmp; // 把最大值赋值给 当前坐标的值 int minTmp=arr[i]; arr[i] = arr[minIndex]; // 把最小值赋值给 当前坐标的值 arr[minIndex]=minTmp; }else{ int maxTmp = arr[length - i - 1]; int minTmp=arr[minIndex]; arr[length - i - 1] = arr[maxIndex]; arr[maxIndex] = maxTmp; // 把最大值赋值给 当前坐标的值 arr[minIndex]=tmp; arr[i]=minTmp; } } } }