Eight Sorts Java Edition | Full Handwriting | Você pode executar a versão diretamente no Bloco de Notas

Se você deseja executá-lo no Bloco de Notas, você precisa alterar o nome do Bloco de Notas para ClassName.java , javac 类名.javacompilar o arquivo e java 类名executar

Tipo de bolha

  • O princípio do bubble sort é muito simples:
    • Percorra a matriz, compare o tamanho dos dois números antes e depois de cada vez e mova o número maior de volta.
    • Então você precisa executar a travessia de comprimento-1 da matriz.
public class Bubble {
    public static void main(String[] args) {
        int[] nums = {341,92,1,7,432,66,78,9};
        Bubble(nums);
        for (int num : nums) {
            System.out.print(num);
        }
    }

    public static void Bubble(int[] nums){
        for(int i = nums.length - 1;i > 0;i --){//注意,这里i从大到小倒叙
            for(int j = 0;j < i;j ++){
                if(nums[j] > nums[j + 1]){
                    int temp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
                }
            }
        }
    }
}

classificação de seleção

  • Assumindo que o número representado pelo índice atual é o menor valor, o índice é chamado de menor índice. Percorra a matriz e, se encontrar um número menor que o número atual, troque o índice pelo menor índice. Após completar uma travessia, o número representado pelo índice mínimo é o valor mínimo, e a posição pode ser trocada pelo número atual.
  • Faça o comprimento da matriz - 1 travessia
public class Choose {
    public static void main(String[] args) {
        int[] nums = {341,92,1,7,432,66,78,9};
        Choose(nums);
        for(int num:nums){
            System.out.print(num);
        }
    }

    public static void Choose(int[] nums){
        for(int i = 0;i < nums.length - 1;i ++){
            int minIndex = i;
            for(int j =i+1;j < nums.length;j ++){
                if(nums[j] < nums[minIndex]){
                    minIndex = j;
                }
            }
            int temp = nums[minIndex];
            nums[minIndex] = nums[i];
            nums[i] = temp;
        }
    }
}

Classificação de inserção

  • Divida a matriz a ser classificada em duas partes: a matriz classificada e a matriz não classificada.
  • Pegue o primeiro número do array não ordenado, percorra o array ordenado ao contrário e compare-o com o número do array ordenado.Se o número for menor que o número no array ordenado, troque as posições.
public class Insert {
    public static void main(String[] args) {
        int[] nums = {341,92,1,7,432,66,78,9};
        Insert(nums);
        for (int num : nums) {
            System.out.print(num);
        }
    }

    public static void Insert(int[] nums){
        for(int i = 0;i < nums.length - 1;i ++){
            for(int j = i;j >= 0;j --){
                if(nums[j + 1] < nums[j]){
                    int temp = nums[j + 1];
                    nums[j + 1] = nums[j];
                    nums[j] = temp;
                }
            }
        }
    }
}

Classificação do monte

  • Defina o comprimento do incremento h para que a matriz seja dividida em vários grupos e os dois números em cada grupo sejam comparados e trocados
    • Reduza o comprimento do incremento e termine a ordenação quando h<1
  • Na classificação de Hill, não há uma regra fixa para a quantidade de crescimento h; eu assumo um método limitante de h aqui
public class Shell {
    public static void main(String[] args) {
        int[] nums = {341,92,1,7,432,66,78,9};
        Shell(nums);
        for (int num : nums) {
            System.out.print(num);
        }
    }

    public static void Shell(int nums[]){
        int N = nums.length;
        //一种h的定义方法
        int h = 1;
        while(h < N / 2){
            h =  h * 2 + 1;
        }

        while(h >= 1){
            for(int i = h;i < N;i ++){
                for(int j = i;j >= h;j -= h){
                    if(nums[j-h] > nums[j]){
                        int temp = nums[j-h];
                        nums[j-h] = nums[j];
                        nums[j] = temp;
                    }else{
                        break;
                    }
                }
            }
            h = h/2;
        }
    }
}

classificação de mesclagem

  • Classifique primeiro, depois mescle
    • dividir e conquistar
    • faz uso de recursão (então não pode esquecer a condição de saída)
    • Um array auxiliar é usado, que é usado na mesclagem e, finalmente, o conteúdo do array auxiliar é retornado ao array original

public class Merge {
    public static void main(String[] args) {
        int[] nums = {341,92,1,7,432,66,78,9};
        sort(nums);
        for (int num : nums) {
            System.out.print(num);
        }
    }
    static int[] assist;
    public static void sort(int[] nums){
        assist =  new int[nums.length];
        int lo = 0;
        int hi =  nums.length - 1;
        sort(nums,lo,hi);
    }

    public static void sort(int[] nums, int lo, int hi) {
        if(hi <= lo){
            return;
        }
        int mid = lo + (hi-lo)/2;
        sort(nums,lo,mid);//分1
        sort(nums,mid+1,hi);//分2
        merge(nums,lo,mid,hi);//治
    }

    public static void merge(int[] nums,int lo,int mid,int hi){
    int i = lo;//指向辅助数组的头
    int p1 = lo;//指向(被分开的)前一个数组的头
    int p2 = mid + 1;//指向(被分开的)后一个数组的头

    while(p1 <= mid && p2 <= hi){//根据两个数组中数的大小,放到辅助数组中
        if(nums[p1] < nums[p2]){
            assist[i++] = nums[p1++];
        }else{
            assist[i++] = nums[p2++];
        }
    }

    while(p1 <= mid){//清空(被分开的)前一个数组,全部放到辅助数组
        assist[i++] = nums[p1++];
    }
    while(p2 <= hi){清空(被分开的)后一个数组,全部放到辅助数组
        assist[i++] = nums[p2++];
    }

        for(int index = lo;index <= hi;index ++){//辅助数组的内容还给原数组
            nums[index] =  assist[index];
        }
    }
}

ordenação rápida

  • O princípio da classificação rápida é semelhante à classificação por mesclagem, mas a classificação por mesclagem é dividida no meio e precisa ser combinada após a divisão. E a classificação rápida precisa projetar um algoritmo para encontrar um valor de segmento, classificamos cada segmento que é segmentado
  • Algoritmo para encontrar o valor de segmentação: Assumindo que nosso primeiro elemento é o valor de segmentação, nós o ajustamos para que seja chamado de valor de segmentação real: defina um ponteiro para a cabeça e um ponteiro para o próximo bit da cauda, ​​uma varredura para trás , para quando um certo número (subscrito à esquerda) é varrido for maior que o valor de segmentação assumido; uma varredura para frente para quando um certo número (subscrito à direita) é varrido menor que o valor de segmentação assumido.
    • Se esquerda >= direita, saia diretamente. Neste momento, geralmente esquerda == direita, e seus valores atingiram os requisitos do valor de segmentação. Trocamos esse valor com o primeiro elemento para atingir o objetivo.
    • Caso contrário, as posições dos dois números devem ser trocadas de modo que o da esquerda seja menor que o valor da divisão e o da direita seja maior do que o valor da divisão. Continue esta operação com um loop while.
public class Quick {
    public static void main(String[] args) {
        int[] nums = {341,92,1,7,432,66,78,9};
        sort(nums);
        for (int num : nums) {
            System.out.print(num);
        }
    }

    public static void sort(int[] nums){
        int lo = 0;
        int hi = nums.length - 1;
        sort(nums,lo,hi);
    }

    public static void sort(int[] nums,int lo,int hi){
        if(lo >= hi){ 
            return;
        }
        int p1 = part(nums,lo,hi);//找出切分值
        sort(nums,lo,p1-1);
        sort(nums,p1+1,hi);
    }

    public static int part(int[] nums, int lo, int hi){
        int key = nums[lo];
        int left = lo;
        int right = hi + 1;
        while(true){
            while(key < nums[--right]){
                if(right == lo){
                    break;
                }
            }
            while(key > nums[++left]){
                if(left == hi){
                    break;
                }
            }

            if(left >= right){
                break;
            }else{
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
            }
        }
        int ktemp = nums[lo];
        nums[lo] = nums[right];
        nums[right] = ktemp;

        return right;
    }
}

classificação de pilha

  • A classificação de heap precisa construir o heap primeiro e depois classificá-lo. O que usamos aqui é o big top heap, o chamado big top heap é de cima para baixo, e os números são de grande para pequeno. Então, trocamos o primeiro e o último não classificado do grande heap superior a cada vez (após cada troca, precisamos realizar um afundamento para garantir as características de seu grande heap superior), para que, após a conclusão da troca, possamos obter de classificação de pequeno a grande porte.
  • Como construir um grande heap superior? Escaneie para a frente a partir da metade, continue afundando.
  • Claro, não se esqueça de retornar o conteúdo do heap para o array.
public class HeapSort {
    public static void main(String[] args) {
        int[] nums = {341,92,1,7,432,66,78,9};
        sort(nums);
        for(int num:nums){
            System.out.print(num);
        }
    }

    public static void sort(int[] nums){
        //1.建立堆heap|堆的0号位置是空出来的,所以用一个新的数组进行复刻
        int[] heap = new int[nums.length + 1];
        System.arraycopy(nums,0,heap,1,nums.length);
        for(int i = (heap.length - 1) / 2;i > 0;i --){//这里是>0不是>=0!!!!!!!!!!
            sink(heap,i,heap.length-1);//-1是因为堆长度多出来一位
        }


        //2.排序|交换堆顶元素和最后一个元素并下沉
        for(int i = heap.length - 1;i > 1;i--){
            int temp = heap[i];
            heap[i] = heap[1];
            heap[1] = temp;
            sink(heap,1,i-1);//这里i-1也很容易错
        }


        //3.收尾工作,把堆还给nums
        System.arraycopy(heap,1,nums,0,nums.length);
    }


    //下沉
    //找到子节点中较大的值的下标,如果target < 较大的值,就需要交换
    //大大的问题,堆的大小直接显示在序号上了//这里max代表的是下标
    public static void sink(int[] heap,int target,int range){
        while(2 * target <= range){//至少左子节点
            int max = 2 * target;//这里max代表的是下标
            if(2 * target + 1 <= range){//如果存在右子节点
                if(heap[2 * target + 1] > heap[2 * target]){
                    max = 2 * target + 1;
                }
            }

            if(heap[target] < heap[max]){//如果target < 较大的值,就需要交换
                int temp = heap[target];
                heap[target] = heap[max];
                heap[max] = temp;
            }

            //更新target的值,进行下一个
            target = max;
        }
    }
}

Classificação Radix (também chamada de classificação por bucket)

  • A classificação básica precisa classificar cada bit (um, dez, cem, mil, dez mil), e a classificação de cada bit precisa ser colocada no bucket e, em seguida, a matriz é recuperada, para que cada bit tenha uma ordem
    • Primeiro, determine qual é o seu dígito mais alto, encontre o maior número e o número de dígitos no maior número é o dígito mais alto
    • fazer um barril, fazer um contador
    • Operação de loop (coloque no bucket, recupere o array)
package com.zhang.eightsort;
public class BaseSort {
    public static void main(String[] args) {
        int[] nums = {341,92,1,7,432,66,78,9};
        sort(nums);
        for (int num : nums) {
            System.out.print(num+" ");
        }
    }
    
    public static void sort(int[] nums){
        //1.找出最大位是哪一位|    先找最大的数,然后看他的位数
        int maxNum = nums[0];
        for (int i = 0; i < nums.length; i++) {
            if(nums[i] > maxNum){
                maxNum = nums[i];
            }
        }//331
        int maxLen = Integer.toString(maxNum).length();//3
        
        
        //2.开始造桶  10 x nums.length
        //并且把数据都放进桶里
        int[][] bucket = new int[10][nums.length];
        int[] counts = new int[10];//创建10个计数器
        int div = 1;
        for(int i = 0;i < maxLen;i ++){//每次都要放进桶再拿出来
            for(int j = 0 ;j < nums.length;j ++){
                int temp = nums[j] / div % 10;//比如说余3
                bucket[temp][counts[temp]++] = nums[j];
            }
            div *= 10;
        int total = 0;
        //从桶里把数据放回数组
        for(int n = 0;n < 10;n++){//10 个桶
            for(int j = 0;j < counts[n];j ++){
                nums[total++] = bucket[n][j];//total别忘了++
            }
            counts[n] = 0;//这个清空桶的操作还挺关键,不然会数组下标越界
        }
    }//这个括号放在这也有讲究,每排一次都要放回一次数组中。
    }
}

おすすめ

転載: blog.csdn.net/dolpin_ink/article/details/123488937