Resumen del algoritmo de clasificación de Java (clasificación común)

        Podemos aprender cosas nuevas al revisar el pasado. Los algoritmos de clasificación no son difíciles. Normalmente clasificamos. Java viene con algoritmos de clasificación. Al igual que los algoritmos de clasificación que vienen con las colecciones, la implementación subyacente es la clasificación por fusión y la clasificación por árbol binario. puede comprobarlo.

       Hablemos de algoritmos de clasificación comunes. No es particularmente esotérico. Simplemente escriba un código y revise algunas ideas e implementaciones del algoritmo.

1. Clasificación de burbujas,

         No hablaré de esto, solo ve al código, lo aprendí cuando entré por primera vez en contacto con el algoritmo.

  /**
     * 冒泡排序
     * 时间复杂度O(n*n)
     * @param list
     * @return
     */
    public static List<Integer> sortByBob(List<Integer> list){
        if(list.isEmpty()){
            return new ArrayList<>();
        }
        int length = list.size();
        for (int i = 0; i < list.size(); i++) {
            for (int j = 0; j < length-1-i; j++) {
                if(list.get(j)>list.get(j+1)){
                    int temp = list.get(j);
                    list.set(j,list.get(j+1));
                    list.set(j+1,temp);
                }
            }
        }
        System.out.println(JSONArray.toJSONString(list));
        return list;
    }

2. Elija un tipo

       Clasificación de selección, siento que es más fácil de entender, incluso yo siempre pensé que la clasificación de selección es clasificación de burbujas, porque es una comparación, la complejidad del algoritmo también es O (n * n), esto es bueno para que todos lo entiendan, generalmente rara vez Es demasiado caro de usar y no es rentable. Echemos un vistazo al código.

  /**
     * 选择排序,和冒泡排序时间复杂度一样,更容易理解
     * 时间复杂度O(n*n)
     * @param list
     * @return
     */
    public static List<Integer> sortByChoose(List<Integer> list){
        if(list.isEmpty()){
            return new ArrayList<>();
        }

        for (int i = 0; i < list.size(); i++) {
            for (int j = i+1; j < list.size(); j++) {
                if(list.get(i)>list.get(j)){
                    int temp = list.get(i);
                    list.set(i,list.get(j));
                    list.set(j,temp);
                }
            }
        }
        System.out.println(JSONArray.toJSONString(list));
        return list;
    }

3. Orden de inserción

       Esta también es una clasificación básica. Se siente que consume menos rendimiento que la clasificación de burbujas. Sin embargo, en el peor de los casos, la complejidad temporal también es O (n * n). Generalmente, la complejidad temporal de la clasificación de inserción predeterminada es O ( n * n), este tipo presta atención, mira el código.

 /**
     * 插入排序
     * 插入排序思想容易理解,写起来比较绕,就是把j位置上的值往前一位设置,判断当前的数据小于某一位时,停止复制,
     *           把预存的i位置的值赋上去
     * 这个感觉时间复杂度比冒泡少,但是实际上平均时间复杂度是n^2/4+n/2-1/2,最差的结果也是n^2
     * @param list
     * @return
     */
    static public List<Integer> sortByInsert(List<Integer> list){

        for (int i = 1; i < list.size(); i++) {
            int j ;
            if(list.get(i-1)>list.get(i)){
                int temp = list.get(i);
                for (j = i-1;j>=0&&temp<list.get(j);j--){
                    list.set(j+1,list.get(j));
                }
                list.set(j+1,temp);
            }
        }
        System.out.println(JSONArray.toJSONString(list));
        return list ;
    }

4. Clasificación rápida

         La ordenación rápida es una idea recursiva por partes, con una complejidad de tiempo de nlogN, que es un algoritmo de ordenación relativamente maduro. Está bien, mira el código.

 /**
     * 快速排序
     * (1)首先设定一个分界值,通过该分界值将数组分成左右两部分。 [2]
     * (2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
     * (3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
     * (4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
     * @return
     */
    public static List<Integer> quickSort(List<Integer> list,Integer start,Integer end){
        if (list.isEmpty()) return new ArrayList<>();
        int i = start;
        int j = end;
        int mark = list.get(start);

        while (i<j){
            while ((i<j)&&list.get(j)>mark){
                j--;
            }
            while ((i<j)&&(list.get(i)<mark)){
                i++;
            }
            if((list.get(i)==list.get(j))&&i<j){
                i++;
            }else {
                int temp = list.get(i);
                list.set(i,list.get(j));
                list.set(j,temp);
            }
        }
        if(i-1>start) list = quickSort(list,start,i-1);
        if(j+1<end) list = quickSort(list,j+1,end);

        return list;
    }

5. Combinar y ordenar

       Se debería decir que este algoritmo de ordenación es relativamente cercano a nuestro uso. También dije anteriormente que la ordenación por combinación se usa en la ordenación de conjuntos. Además, la ordenación en MYSQL también es una ordenación por combinación. La ordenación por fusión es más fácil de entender y eficiente, pero consume más memoria, pero este consumo es aceptable para la mayoría de los sistemas. Eche un vistazo al código.

 /**
     * 归并排序递归
     * @param list
     * @param left
     * @param right
     * @return
     */
    public static List<Integer> mergeSort(List<Integer> list,int left,int right){
        if(left<right){
            int mid = (left+right)/2;
            mergeSort(list,left,mid);
            mergeSort(list,mid+1,right);
            mergePlatfrom(list,left,mid,right);
        }
        return list;
    }

    /**
     * 归并排序是底层实现
     * @param list
     * @param left
     * @param mid
     * @param right
     */
    static public void mergePlatfrom(List<Integer> list,int left,int mid,int right){
        List<Integer> temp = new ArrayList<>();  //存放排序后的新队列
        int i = left;
        int j = mid+1;
        int t = 0;
        while (i<=mid && j<=right){ //归并会从中间分开,从两侧依次拿出一个数据进行对比,然后放到新数据集合里面,这样新的数据集合里面的数据就是有序的
            if(list.get(i)<=list.get(j)){
                temp.add(list.get(i++));
            } else {
                temp.add(list.get(j++));
            }
        }
        //表示左侧的数据很大,右侧的数据已经比完了,左侧还有多个数据,因为默认是有序的(会递归),所以直接放进新的数据集合里
        while (i<=mid){
            temp.add(list.get(i++));
        }
        //同理,表示右侧的数据很大,左侧的数据已经比完了,右侧还有多个数据,默认有序(会递归),也直接放进新的数据集合里
        while (j<=right){
            temp.add(list.get(j++));
        }
        //把排序后的新的数据集合放到原来的数据集合里面
        t = 0;
        while (left <= right){
            list.set(left++,temp.get(t++));
        }
    }

      El código no es particularmente clásico, pero es bastante simple y fácil de entender, e implementa la lógica principal del algoritmo. Los amigos que quieran revisar el algoritmo de clasificación pueden comprobarlo.

Sin sacrificio, sin victoria ~

 

Supongo que te gusta

Origin blog.csdn.net/zsah2011/article/details/109057866
Recomendado
Clasificación