导航

选择排序

Posted on 2020-04-11 21:33  少吃多动早睡  阅读(127)  评论(0)    收藏  举报

选择排序就是找出该数组的最小数min,然后min放到数组的arr[0],然后再找出除去min后最小的数min2,将min2放到arr[1]........以此类推.如下图

 

 

 代码实现:

package com.bigData.leetcode.SortAlgorithm;

/**
 * 选择排序算法  升序排序     遍历一轮,找到最小的那个数,然后与数组index=0的数变换位置,然后找第二小的数,和index=1的数变换位置,,,如此反复
 * question:  一次查找最大最小值的时候,最后在交换的时候,可能出现,将最小值的排好以后,可能会出现将之前取得最大值的索引改变的情况
 */
public class SelectSort {
    public static void main(String[] args) {
        int[] arr = {1, 3, 2, 5, 88, 608, 44, 7, 9, 0, 8, 11, 99, 77, 4564, 789, 41, 44, 6, 18, 48, 156, 46546};

//        int[] newarr = sortByOneIndex(arr);
//        print(newarr);
        sortByTwoIndex(arr);
    }

    static int[] sortByTwoIndex(int[] arr) {

        //定义两个指针,最小and最大
        for (int j = 0; j < (arr.length / 2); j++) { //循环的次数   这里要设置j<arr.length/2   因为同时获取最大最小值,所以循环次数为只获取最小值的一半,
            int minPos = j;//0,1,2,3....
            int maxPos = j;//9,8,7,6,......
            int maxTep = 0;
            for (int i = j + 1; i < arr.length - j; i++) {//这里之前 写的i<arr.length   是不对的,这种情况只是考虑了左边开始索引的变化,
                // 没有考虑右边索引开始的变化,左边索引变大,右边索引变小
                minPos = arr[i] < arr[minPos] ? i : minPos;
                maxPos = arr[i] > arr[maxPos] ? i : maxPos;
                maxTep = arr[maxPos];
            }
            System.out.println("第" + j + "次循环+minPos=" + minPos + "," + "maxPos=" + maxPos);
            //一轮循环完成后,找到min和max的值,min和arr[0]调换值,max和arr[arr.length-1] 调换
            swap(arr, minPos, j);
            if (maxTep == arr[maxPos]) {//这个判断是避免上面将最小值arr[minPos]与arr[j]交换完毕以后,改变了第j个最大值的maxPos,就是arr[maxPos]不再是第i大的数据
                swap(arr, maxPos, arr.length - 1 - j);//16 -1 -j
            } else {//循环倒退一次,这样就避免了上面的问题
                j--;
            }
        }
        return arr;
    }


    static int[] sortByOneIndex(int[] arr) {

        //定义一个minpos
        for (int i = 0; i < arr.length - 1; i++) {  //循环的次数
            int minPos = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[minPos] > arr[j])
                    minPos = j;//找到更小的数,minPos指向该数的位置
            }
            System.out.println("minPos=" + minPos);
            //遍历一轮,找到最小的数,然后调换位置
//            int tmp = arr[minPos];
//            arr[minPos] = arr[i];
//            arr[i] = tmp;
            swap(arr, minPos, i);
        }
        print(arr);
        return arr;
    }

    static void print(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }

    /**
     * 调换数组两个值
     *
     * @param arr
     * @param index1
     * @param index2
     */
    static void swap(int[] arr, int index1, int index2) {
        int tmp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = tmp;
    }
}

一次查找一个最小或者最大数然后排列的方法是比较简单的,这一次主要学习到了当一次循环里面查找第j大和第j小的数,当最小数交换成功后可能会导致 arr[maxPos]不再是第i大的数据 的问题