文章目录
- 排序分类/排序算法的分类
- 冒泡排序
- 代码1:
- 代码2(优化
- 代码3(算法优化 --当次排序没有进行交换则退出循环
- 代码4(封装为方法
- 代码5(检测冒泡排序时间复杂度
 
- 选择排序
- 代码1
- 代码2(优化算法
- 代码3(计算时间复杂度
 
- 插入排序
- 代码
- 时间复杂度
 
- 希尔排序
- 交换法
- 时间复杂度
- 移位法(效率高
 
排序分类/排序算法的分类

冒泡排序
介绍
 
模拟/思路讲解
 
数组转换成String类型输
代码1:
package Sort;
import java.lang.reflect.Array;
import java.util.Arrays;
public class BubbleSort {
    public static void main(String[] args) {
        int arr[] = {3,9,-1,10,-2};//从小到大排序
        //第一趟排序 就是将最大的数排在最后
        int temp = 0;//临时变量
        for (int i = 0; i < arr.length-1; i++) {
            if (arr[i] > arr[i+1]){
                temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }
        System.out.println("第一趟排序后的数组:");
        //???toString
        System.out.println(Arrays.toString(arr));
        //第二趟排序 就是第二大的数排在倒数第二位
        for (int i = 0; i < arr.length - 2; i++) {
            if (arr[i] > arr[i+1]){
                temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }
        System.out.println("第二趟排序后的数组:");
        //???toString
        System.out.println(Arrays.toString(arr));
        //第三趟排序 就是将第三大的数排在倒数第三位
        for (int i = 0; i < arr.length - 3; i++) {
            if (arr[i] > arr[i+1]){
                temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }
        System.out.println("第三趟排序后的数组:");
        //???toString
        System.out.println(Arrays.toString(arr));
        //第四趟排序 就是将第四大的数排在倒数第三位
        for (int i = 0; i < arr.length - 4; i++) {
            if (arr[i] > arr[i+1]){
                temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }
        System.out.println("第四趟排序后的数组:");
        //???toString
        System.out.println(Arrays.toString(arr));
    }
}
代码2(优化
package Sort;
import java.lang.reflect.Array;
import java.util.Arrays;
public class BubbleSort {
    public static void main(String[] args) {
        int arr[] = {3,9,-1,10,-2};//从小到大排序
        //第一趟排序 就是将最大的数排在最后
        int temp = 0;//临时变量
        for (int i = 0; i < arr.length-1; i++) {
            for (int j = 0; j < arr.length-1-i; j++) {
                if (arr[j] > arr[j+1]){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
            System.out.println("第"+(i+1)+"趟排序后的数组:");
            System.out.println(Arrays.toString(arr));
        }
    }
}

代码3(算法优化 --当次排序没有进行交换则退出循环
package Sort;
import java.lang.reflect.Array;
import java.util.Arrays;
public class BubbleSort {
    public static void main(String[] args) {
        int arr[] = {3,-1,9,10,20};//从小到大排序
        //第一趟排序 就是将最大的数排在最后
        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++) {
                if (arr[j] > arr[j+1]){
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
            System.out.println("第"+(i+1)+"趟排序后的数组:");
            System.out.println(Arrays.toString(arr));
            if (!flag){
                break;
            }else {
                flag = false;
            }
        }
    }
}

代码4(封装为方法

代码5(检测冒泡排序时间复杂度
package Sort;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class BubbleSort {
    public static void main(String[] args) {
//        int arr[] = {3,-1,9,10,20};//从小到大排序
        int[] arr = new int[80000];
        for (int i = 0; i < 80000; i++) {
            arr[i] = (int)(Math.random() * 8000000);//生成[0,8000000)的数
        }
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1Str = simpleDateFormat.format(date1);
        System.out.println("排序前的时间是="+date1Str);
        //测试冒泡排序
        bubbleSort(arr);
        Date date2 = new Date();
        String date2Str = simpleDateFormat.format(date2);
        System.out.println("排序后的时间是="+date2Str);
    }
    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++) {
                if (arr[j] > arr[j+1]){
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
//            System.out.println("第"+(i+1)+"趟排序后的数组:");
//            System.out.println(Arrays.toString(arr));
            if (!flag){
                break;
            }else {
                flag = false;
            }
        }
    }
}

冒泡排序时间复杂度:O(n2 )
选择排序
选择排序思路:
 
图解流程:
 
代码1
package Sort;
import java.util.Arrays;
public class SelectSort {
    public static void main(String[] args) {
        int[] arr = {101, 119, 34,1};
        System.out.println("排序前:");
        System.out.println(Arrays.toString(arr));
        selectSort(arr);
    }
    public static void selectSort(int[] arr) {
        //第1轮
        int minIndex = 0;
        int min = arr[0];
        for (int i = 0 + 1; i < arr.length; i++) {
            if (min > arr[i]) {//说明假定的最小值不是最小的
                min = arr[i];   //重置min
                minIndex = i;   //重置minIndex
            }
        }
//        System.out.println("minIndex = "+minIndex);
//        System.out.println("min = "+min);
        //将最小值元素与arr[0] 两者交换
        if (minIndex != 0){
            arr[minIndex] = arr[0];
            arr[0] = min;
        }
        System.out.println("第1轮后:");
        System.out.println(Arrays.toString(arr));
        //第2轮
         minIndex = 1;
         min = arr[1];
        for (int i = 1 + 1; i < arr.length; i++) {
            if (min > arr[i]) {//说明假定的最小值不是最小的
                min = arr[i];   //重置min
                minIndex = i;   //重置minIndex
            }
        }
        //将最小值元素与arr[0] 两者交换
        if (minIndex != 1){
            arr[minIndex] = arr[1];
            arr[1] = min;
        }
        System.out.println("第2轮后:");
        System.out.println(Arrays.toString(arr));
        //第3轮
         minIndex = 3;
         min = arr[3];
        for (int i = 2 + 1; i < arr.length; i++) {
            if (min > arr[i]) {//说明假定的最小值不是最小的
                min = arr[i];   //重置min
                minIndex = i;   //重置minIndex
            }
        }
        //将最小值元素与arr[0] 两者交换
        if (minIndex != 3){
            arr[minIndex] = arr[2];
            arr[2] = min;
        }
        System.out.println("第3轮后:");
        System.out.println(Arrays.toString(arr));
    }
}

代码2(优化算法
package Sort;
import java.util.Arrays;
public class SelectSort {
    public static void main(String[] args) {
        int[] arr = {101, 119, 34,1,-1,90,123};
        System.out.println("排序前:");
        System.out.println(Arrays.toString(arr));
        selectSort(arr);
        System.out.println("排序后:");
        System.out.println(Arrays.toString(arr));
    }
    public static void selectSort(int[] arr) {
        for (int i = 0; i < arr.length-1; i++) {
            //第1轮
            int minIndex = i;
            int min = arr[i];
            for (int j = i + 1; j < arr.length; j++) {
                if (min > arr[j]) {//说明假定的最小值不是最小的
                    min = arr[j];   //重置min
                    minIndex = j;   //重置minIndex
                }
            }
            //将最小值元素与arr[0] 两者交换
            if (minIndex != i){
                arr[minIndex] = arr[i];
                arr[i] = min;
            }
//            System.out.println("第"+(i+1)+"轮后:");
//            System.out.println(Arrays.toString(arr));
        }
    }
}

选择排序的时间复杂度是O(n2 )
比冒泡排序快的原因:
多了个判断筛选,减小循环次数
代码3(计算时间复杂度
main内
//计算选择排序的时间复杂度
        int[] arr = new int[80000];
        for (int i = 0; i < 80000; i++) {
            arr[i] = (int)(Math.random() * 8000000);//生成[0,8000000)的数
        }
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1Str = simpleDateFormat.format(date1);
        System.out.println("排序前的时间是="+date1Str);
        //测试冒泡排序
        selectSort(arr);
        Date date2 = new Date();
        String date2Str = simpleDateFormat.format(date2);
        System.out.println("排序后的时间是="+date2Str);

插入排序
思想
 
 思路图
 
代码
package Sort;
import java.util.Arrays;
public class InsertSort {
    public static void main(String[] args) {
        //从小到大
        int[] arr = {101,34,119,1,-1,89};
        insertSort(arr);
    }
    public static void insertSort(int[] arr){
        for (int i = 1; i < arr.length; i++) {
            int insertVal = arr[i];
            int insertIndex = i-1;  //arr[1]前面数的下标
            //1.insertIndex >= 0:保证不越界
            //2.insertVal < arr[insertIndex]还没找到插入位置
            while (insertIndex >= 0 && insertVal < arr[insertIndex]){
                arr[insertIndex+1] = arr[insertIndex]; //将arr[insertIndex]后移
                insertIndex--;//让arr[1]再和前面的数进行比较
            }
            //当退出while循环时 说明插入的位置找到 insertIndex+1(因为
            // 1.insertIndex可能--多了
            // 2.就算arr[1]=334则一开始不需要insertIndex-1
            arr[insertIndex + 1] = insertVal;
            System.out.println("第"+i+"轮插入:");
            System.out.println(Arrays.toString(arr));
        }
    }
}
优化:
if (insertIndex+1 != i){
                arr[insertIndex + 1] = insertVal;
            }
例如arr[1]一开始为334 则不需要任何交换排序
时间复杂度
main内
int[] arr = new int[80000];
        for (int i = 0; i < 80000; i++) {
            arr[i] = (int)(Math.random() * 8000000);//生成[0,8000000)的数
        }
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1Str = simpleDateFormat.format(date1);
        System.out.println("排序前的时间是="+date1Str);
        //测试冒泡排序
        insertSort(arr);
        Date date2 = new Date();
        String date2Str = simpleDateFormat.format(date2);
        System.out.println("排序后的时间是="+date2Str);

希尔排序
插入排序存在的问题-效率低下
 
 希尔排序图解
 
 
 希尔排序的两种应用方法
 
交换法
package Sort;
import java.util.Arrays;
public class ShellSort {
    public static void main(String[] args) {
        int[] arr = {8,9,1,7,2,3,5,4,6,0};
        shellSort1(arr);
    }
    //使用交换法
    public static void shellSort1(int[] arr){
        int temp = 0;
        int count = 0;
        //第1轮
        //10个数据分为了5组
        for(int gap = arr.length/2;gap > 0;gap /= 2){
            for (int i = gap; i < arr.length; i++) {
                //遍历各组中所有的元素(共gap组) 步长为gap
                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;
                    }
                }
            }
            System.out.println("希尔排序的第"+(++count)+"轮 = "+ Arrays.toString(arr));
        }
    }
}

时间复杂度
代码同上
 
反而比插入排序更慢了
加上弹幕说的break后时间变成了不到1秒,why啊!?谢谢你陌生人(呵呵
答案:减少forj的循环判断
移位法(效率高
//使用交换法
    public static void shellSort1(int[] arr){
        int temp = 0;
        int count = 0;
        //第1轮
        //10个数据分为了5组
        for(int gap = arr.length/2;gap > 0;gap /= 2){
            for (int i = gap; i < arr.length; i++) {
                //遍历各组中所有的元素(共gap组) 步长为gap
                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;
                        break;
                    }
                }
            }
//            System.out.println("希尔排序的第"+(++count)+"轮 = "+ Arrays.toString(arr));
        }

效率也比方法一高





![[BJDCTF2020]Easy MD5(浅谈PHP弱类型hash比较缺陷)](https://img-blog.csdnimg.cn/44a98362352b4eaa8996fc10d4c26504.png)













