冒泡、选择、插入和希尔排序

冒泡排序

public class BubbleSort {
    /*
       基本思想:
       通过对待排序序列从前往后(从下标较小的元素开始),依次比较相邻两元素的值,若发现逆序则交换,
       使值较大的元素逐渐从前面移向后部。
       以从小到大为例:每一趟都确定一个当前最大数的位置,共走n-1趟。
     */
    public static  void bubbleSort(int[] arr){
        //临时变量,用来交换数组不同位置的两个数
        int temp = 0;
        //优化效率的一个标志
        boolean flag= false;

        for(int i=0;i<arr.length-1;i++){
            for (int j = 0; j <arr.length-1-i; j++) {
                //“-i"每一轮冒泡以后最大数已经就位,没有必要重复比较
                if(arr[j]>arr[j+1]){
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                    //在该轮中如果进行过交换则将flag更改为true
                    // (如果flag一次都没有进行过交换则为false,证明此时数组已经是一个有序数组,可以直接退出程序)
                    flag=true;
                }
            }
            if(!flag){
                break;
            }else {
                flag=false;
            }
        }
    }
}

选择排序

/*
    基本思想:
        第一次从arr[0]-—arr[n-1]中找到最小的数与arr[0]交换;第二次从arr[1]--arr[n-1]
    中找到最小的数与arr[1]交换,以此类推,直到完成排序。
    说明:
    1.选择排序一共有数组大小-1次排序;
    2.每一轮排序都是一个循环
        2.1先假定当前这个数最小;
        2.2然后和后面的每个数进行比较,如发现比前面更小的数就重新确定最小数并确定下标;
        2.3当打到最后时,就找到了本轮的最小数;
        2.4进行交换。
     */
    //时间复杂度O(n2)
    public static void selectSort(int[] arr){
        for(int i=0;i<arr.length-1;i++){
            int minIndex = i;
            int min = arr[i];
            //(i+1)从上一轮的下一个开始选择
            for(int j=i+1;j<arr.length;j++){
                if(min>arr[j]){
                    //找到本轮的最小数和他的下标
                    min=arr[j];
                    minIndex=j;
                }
            }
            //交换
            if(minIndex!=i){
                arr[minIndex] = arr[i];
                arr[i]=min;
            }

        }
    }
}

插入排序

public class InsertSort {
    /*
    简单插入排序是对于欲排序的元素已插入的方式找到该元素的位置,以达到排序的目的
    基本思想:
        把n个待排序的元素看成一个有序表和无序表
        开始时有序表中只有一个元素,无序表中有n-1个元素,排序过程中每一次从无序表
    中取出第一个元素,把他的排序码与有序表中的排序码依次进行比较,将它插入到有序表
    中的适当位置,使之成为新的有序表。
     */
    public static void insertSort(int[] arr){
        for(int i=1;i<arr.length;i++){
            int value = arr[i];//待插入的数
            int Index = i-1;//待插入数的前一个数的坐标(待插入数与有序表中第一个数比较的下标)
            //保证不越界  待插入数的位置还没有找到
            while(Index>=0&&value<arr[Index]){
                //将比待插入数大的移到正确的位置
                arr[Index+1] = arr[Index];
                //继续与下一个比较
                Index--;
            }
            //位置找到,并完成插入
            arr[Index+1]=value;
        }
    }
}

 

希尔排序

/*
    也是一种插入排序
    简单插入排序的问题:如果较小的数排在后面,那么厚仪的次数明显增加,会影响效率

    希尔排序的基本思想:
        把数组按下标的一定增量分组,对每一组使用直接插入排序算法排序;随着增量
     逐渐减少,每组包含的关键词与来越多,当增量减少到1时,完成最后一次简单插入排序
     算法结束。
     */

    //交换法
    public static void shellSort(int[] arr) {
        int temp = 0;
        for(int gap = arr.length / 2; gap > 0; gap /= 2) {
            for(int i = gap; i < arr.length; ++i) {
                for(int j = i - gap; j >= 0; j -= gap) {
                    if (arr[j] > arr[j + gap]) {
                        temp = arr[j];
                        arr[j] = arr[j + gap];
                        arr[j + gap] = temp;
                    }
                }
            }
        }
    }
    //位移法{(效率较高)
    public static void shellSort2(int[] arr) {
        //所谓的增量就是分为几组,在这里就是gap在逐步减小
        for(int gap = arr.length / 2; gap > 0; gap /= 2) {

            //遍历各组中的所有元素,一改组下标最大的元素为起点
            for(int i = gap; i < arr.length; i++) {
                int j = i;
                int temp = arr[i];
                if (arr[i] < arr[i - gap]) {
                    while(j - gap >= 0 && temp < arr[j - gap]) {
                        arr[j] = arr[j - gap];
                        j -= gap;
                    }
                    arr[j] = temp;
                }
            }
        }

    }
}

 

posted @ 2020-12-15 18:46  素色学习  阅读(71)  评论(0编辑  收藏  举报