选择排序的优化

270 阅读1分钟

选择排序代码如下,可以发现,i每次加1,j都会走数组长度减去i次,即为n((n1)+(n2)+...1)=n(n1+1)/2=n2/2n*((n-1)+(n-2)+...1)=n*(n-1+1)/2=n^2/2 ,用大O表示法即为O(n2)O(n^2),现在我尝试说明下通过找出最小元素的同时,找出最大元素,对选择排序简单优化的过程。

选择排序简单实现

/**
 * 选择排序:思路 1. 拿第一个数和其他数比较,找出最小的,交换位置
 *
 * @param nums
 * @return
 */
public static void sort(int[] nums) {
    for (int i = 0; i < nums.length; i++) {
        int minPos = i;

        for (int j = i + 1; j < nums.length; j++) {
            if (nums[j] < nums[minPos])
                minPos = j;
        }

        int temp = nums[i];
        nums[i] = nums[minPos];
        nums[minPos] = temp;
    }
}

选择排序的简单优化

思路:在找出最小元素坐标的时候,找到最大元素坐标,需要做的事有

  1. 增加一个变量,用来记录最大元素的坐标
  2. 当前元素和其后的每个元素相比,获取到大的元素的坐标,赋值给1中的变量
  3. 将最大元素,放到数组长度(减一)减去当前循环次数的那个位置上
  4. 同时,最重要的一步,外层循环只需要执行之前一半的循环 这样,我们就完成了对选择排序的优化 代码如下:

优化后的代码

public static void sortPlus(int[] nums) {

    for (int i = 0; i < nums.length / 2; i++) {
        int minPos = i;
        int maxPos = i;
        for (int j = i + 1; j < nums.length; j++) {
            if (nums[j] < nums[minPos]) {
                minPos = j;
            }
            if (j < nums.length - i  && nums[j] > nums[maxPos]){
                maxPos = j;
            }
        }

        int temp = nums[i];
        nums[i] = nums[minPos];
        nums[minPos] = temp;
        if(minPos==nums.length-i-1 && maxPos==i)
            continue;
        int tempMax = nums[nums.length - i - 1];
        nums[nums.length - i - 1] = nums[maxPos];
        nums[maxPos] = tempMax;
    }
}

注意点

  1. 在进行最大元素的对比时,我们需要排除掉对已排好序部分的对比,否则,会把最右侧的元素拿过来
  2. 如果元素个数为偶数时,会产生,最小值左侧已经排好序,最大值拿到的还是九的数据,又进行了一次交换,相当于覆盖了最小值的交换

感谢阅读