Eight Sorts Java Edition | Escritura a mano completa | Puede ejecutar la versión directamente en el Bloc de notas

Si desea ejecutarlo en el Bloc de notas, debe cambiar el nombre del Bloc de notas a ClassName.java , luego javac 类名.javacompilar el archivo y java 类名ejecutar

Ordenamiento de burbuja

  • El principio de clasificación de burbujas es muy simple:
    • Recorra la matriz, compare el tamaño de los dos números antes y después de cada vez, y mueva el número más grande hacia atrás.
    • Luego, debe realizar un recorrido de longitud de matriz-1.
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;
                }
            }
        }
    }
}

clasificación de selección

  • Suponiendo que el número representado por el índice actual es el valor más pequeño, el índice se llama el índice más pequeño. Recorra la matriz y, si encuentra un número más pequeño que el número actual, intercambie el índice con el índice más pequeño. Después de completar un recorrido, el número representado por el índice mínimo es el valor mínimo y la posición se puede intercambiar con el número actual.
  • Hacer longitud de matriz - 1 recorrido
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;
        }
    }
}

Tipo de inserción

  • Divida la matriz a ordenar en dos partes: la matriz ordenada y la matriz no ordenada.
  • Tome el primer número de la matriz no ordenada, recorra la matriz ordenada en sentido inverso y compárelo con el número de la matriz ordenada a su vez. Si el número es menor que el número de la matriz ordenada, intercambie posiciones.
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;
                }
            }
        }
    }
}

clasificación de colinas

  • Defina la longitud del incremento h para que la matriz se divida en varios grupos y los dos números de cada grupo se comparen e intercambien
    • Reduzca la longitud del incremento y finalice la clasificación cuando h<1
  • En la clasificación Hill, no hay una regla fija para la cantidad de crecimiento h; asumo un método limitante de h aquí
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;
        }
    }
}

ordenar por fusión

  • Ordenar primero, luego fusionar
    • divide y conquistaras
    • hace uso de la recursividad (así que no se puede olvidar la condición de salida)
    • Se usa una matriz auxiliar, que se usa en la combinación y, finalmente, el contenido de la matriz auxiliar se devuelve a la matriz 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];
        }
    }
}

ordenación rápida

  • El principio de la ordenación rápida es similar a la ordenación por combinación, pero la ordenación por combinación se divide por la mitad y debe combinarse después de la división. Y la clasificación rápida necesita diseñar un algoritmo para encontrar un valor de segmento, clasificamos cada segmento que está segmentado
  • Algoritmo para encontrar el valor de segmentación: Asumiendo que nuestro primer elemento es el valor de segmentación, lo ajustamos para que se llame el valor de segmentación real: definimos un puntero a la cabeza y un puntero a la siguiente parte de la cola, un escaneo hacia atrás , se detiene cuando un determinado número (subíndice a la izquierda) escaneado es mayor que el valor de segmentación asumido; un escaneo hacia adelante se detiene cuando un cierto número (subíndice a la derecha) escaneado es menor que el valor de segmentación asumido.
    • Si izquierda >= derecha, salga directamente. En este momento, generalmente izquierda == derecha, y sus valores han alcanzado los requisitos del valor de segmentación. Intercambiamos este valor con el primer elemento para lograr el objetivo.
    • De lo contrario, las posiciones de los dos números deben intercambiarse para que el de la izquierda sea menor que el valor de división y el de la derecha sea mayor que el valor de división. Continúe esta operación con un bucle 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;
    }
}

ordenar en montón

  • Heap sort necesita construir primero el montón y luego ordenarlo. Lo que usamos aquí es el montón superior grande. El llamado montón superior grande es de arriba a abajo, y los números son de mayor a menor. Por lo tanto, intercambiamos el primero y el último sin clasificar del montón superior grande cada vez (después de cada intercambio, debemos realizar un hundimiento para garantizar las características de su montón superior grande), de modo que una vez que se completa el intercambio, podemos lograr desde Clasificación pequeña a grande.
  • ¿Cómo construir un montón superior grande? Escanea hacia adelante desde la mitad, sigue hundiéndote.
  • Por supuesto, no olvide devolver el contenido del montón a la matriz.
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;
        }
    }
}

Clasificación Radix (también llamada clasificación de cubo)

  • La clasificación básica necesita clasificar cada bit (uno, diez, cien, mil, diez mil), y la clasificación de cada bit debe colocarse en el cubo, y luego se retira la matriz, de modo que cada bit tenga un orden.
    • Primero, determine cuál es su dígito más alto, encuentre el número más grande y la cantidad de dígitos en el número más grande es el dígito más alto
    • hacer un barril, hacer un contador
    • Operación de bucle (poner en el cubo, recuperar la matriz)
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;//这个清空桶的操作还挺关键,不然会数组下标越界
        }
    }//这个括号放在这也有讲究,每排一次都要放回一次数组中。
    }
}

Supongo que te gusta

Origin blog.csdn.net/dolpin_ink/article/details/123488937
Recomendado
Clasificación