Resumo do algoritmo de classificação Java (classificação comum)

        Podemos aprender coisas novas revisando o passado. Algoritmos de classificação não são difíceis. Normalmente, nós classificamos. Java vem com algoritmos de classificação. Como os algoritmos de classificação que vêm com as coleções, a implementação subjacente é a classificação por mesclagem e a classificação por árvore binária. Aqueles que estão interessados pode dar uma olhada.

       Vamos falar sobre algoritmos de classificação comuns. Não é particularmente esotérico. Basta escrever algum código e revisar algumas ideias e implementações do algoritmo.

1. Classificação por bolha,

         Não vou falar sobre isso, apenas vou para o código, aprendi quando entrei em contato com o algoritmo pela primeira vez.

  /**
     * 冒泡排序
     * 时间复杂度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. Escolha uma classificação

       O tipo de seleção, eu acho que é mais fácil de entender, mesmo eu sempre pensei que o tipo de seleção é tipo bolha, porque é uma comparação, a complexidade do algoritmo também é O (n * n), isso é bom para todos entenderem, geralmente raramente É muito caro para usar e não é econômico.Vamos dar uma olhada no 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. Classificação de inserção

       Esta também é uma classificação básica. Parece que consome menos desempenho do que a classificação por bolha. No entanto, no pior caso, a complexidade do tempo também é O (n * n). Geralmente, a complexidade do tempo da classificação de inserção padrão é O ( n * n), esse cara preste atenção, olhe o 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. Classificação rápida

         A classificação rápida é uma ideia recursiva por partes, com uma complexidade de tempo de nlogN, que é um algoritmo de classificação relativamente maduro. Ok, olhe para o 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. Mesclar e classificar

       Este algoritmo de classificação deve ser considerado relativamente próximo ao nosso uso. Eu também disse acima que a classificação por mesclagem é usada na classificação de conjuntos. Além disso, a classificação em MYSQL também é classificação por mesclagem. A classificação de mesclagem é mais fácil de entender e eficiente, mas consome mais memória, mas esse consumo é aceitável para a maioria dos sistemas. Dê uma olhada no 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++));
        }
    }

      O código não é particularmente clássico, mas é bastante simples e fácil de entender, e implementa a lógica principal do algoritmo. Amigos que desejam revisar o algoritmo de classificação podem dar uma olhada.

Sem sacrifício, sem vitória ~

 

Acho que você gosta

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