Tipo de algoritmo de clasificación de montón (versión de Java)

La clasificación de pilas utiliza una estructura de datos para la gestión de la información. No solo se usa en la clasificación de montones, también puede construir una cola de prioridad efectiva. Complejidad de tiempo O (nlogn)

montón

El montón (binario) es una matriz, que puede verse como un árbol binario completo aproximado. Cada nodo del libro corresponde a un elemento de la matriz. A excepción de la capa inferior, el árbol está completamente lleno y lleno de izquierda a derecha.

El montón binario se puede dividir en dos formas, el montón más grande y el montón más pequeño.

  • Montón máximo: el valor del nodo principal es mayor o igual que el valor de sus nodos secundarios.
  • Montón mínimo: el valor del nodo principal es menor que el valor de sus nodos secundarios.

Tipo de pila

Lo usamos en el algoritmo de ordenación del montón 最大堆. Llene de izquierda a derecha al llenar.
Inserte la descripción de la imagen aquí

Listo

  • Cuente el número de nodos principales después de que la matriz que se va a ordenar se complete en la estructura del montón
  • Conociendo la posición del nodo principal en la matriz, encuentre las posiciones de los nodos secundarios izquierdo y derecho.
  • Según la posición de cualquier elemento en la matriz, calcule la posición de su nodo padre.

De acuerdo con la imagen de arriba, podemos dibujar la ley.

    /**
     * 根据数组长度计算父节点个数
     *
     * @param pos 数组长度
     * @return 父节点数量
     */
    private static int parent(int len) {
    
    
        return len/2;
    }
    /**
     * 根据子节点所在数组位置,计算父节点位置
     *
     * @param pos 子节点位置
     * @return 父节点位置
     */
    private static int parent(int pos) {
    
    
        return (i-1)/2;
    }
    /**
     * 根据父节点所在数组位置,计算左叶子位置
     *
     * @param pos 父节点位置
     * @return 左子节点位子
     */
    private static int left(int pos) {
    
    
        return 2 * pos + 1;
    }

    /**
     * 根据父节点所在数组位置,计算右叶子位置
     *
     * @param pos 父节点位置
     * @return 右子节点位置
     */
    private static int right(int pos) {
    
    
        return 2 * pos + 2;
    }

Mantenga las propiedades máximas del montón

Concéntrese en el montón de unidades más pequeño (es decir, la matriz tiene solo tres elementos, el nodo principal, la hoja izquierda y la hoja derecha) y manténgalo para mantener su naturaleza de montón máxima.

    /**
     * 对堆结构进行排序,将最大值作为根节点
     *
     * @param array 堆结构对应数组
     * @param pos   排序堆根节点所在数组中的位置
     * @param len   数组长度
     */
    private static void maxHeap(int[] array, int pos, int len) {
    
    
        //计算左右叶子位置
        int l = left(pos);
        int r = right(pos);
        int max = pos;

        if (l < len && array[l] > array[max]) {
    
    
            max = l;
        }
        if (r < len && array[r] > array[max]) {
    
    
            max = r;
        }
        if (max != pos) {
    
    
            int temp = array[pos];
            array[pos] = array[max];
            array[max] = temp;
            //将最大位置的堆再排序,此处是比较绕的点。
            //举例说明:我们先声明二维结构描述,(parent、left、right)
            //堆结构如描述(-3,20,14)(20,6,9)(14,7,8)
            //此时 parent:-3需要和20做交换,交换后为(20,-3,14)(-3,6,9)(14,7,8)
            //此时(-3,6,9)的结构是不对的,所以要对(-3,6,9)的堆结构排序
            //结果为(20,9,14)(9,6,-3)(14,7,8)
            //此时如果-3下还有子节点,还需进行排序(所以递归调用)
            maxHeap(array, max, len);
        }
    }

Construye una pila

Después de poder garantizar la naturaleza del montón máximo, comenzamos a construir el montón de forma ascendente. Es decir, el nodo principal con la posición del elemento más grande se encuentra como el inicio del algoritmo y el vértice del montón se alcanza cuando la posición del elemento llega a 0.

    /**
     * 将数组构建为最大堆结构
     *
     * @param array 数组
     */
    private static void maxHeapBuild(int[] array) {
    
    
        int parentSize = array.length / 2;//计算包含子节点的父节点结束位置
        for (int i = parentSize; i >= 0; i--) {
    
    
            maxHeap(array, i, array.length);
        }
    }

Algoritmo de clasificación de montón

Úselo para maxHeapBuildconstruir el montón máximo; en este momento, el elemento máximo de la matriz está en el vértice, intercambie la posición del elemento de cola con el elemento de vértice y luego elimine el elemento de cola del montón para crear un nuevo montón. Es posible que el nuevo montón no cumpla con las propiedades máximas del montón después de intercambiar posiciones en este momento. Es necesario maxHeapmantener el montón máximo y luego intercambiar con los elementos finales del montón actual, a su vez.

   /**
     * 堆排序
     *
     * @param array 排序数组
     */
    private static void heapSort(int[] array) {
    
    
        //构建最大堆结构, 构建后的array数组并不能保证是有序的
        //但是每个父节点肯定是最大的
        maxHeapBuild(array);
        System.out.println("first build head ::: "+Arrays.toString(array));
        //用来控制数组的排序范围,因为下面要将得到的最大的数值依次放到最后
        int len = array.length;
        for (int i = array.length - 1; i > 0; i--) {
    
    
            System.out.println("root value :: " + array[0]);
            int temp = array[0];
            array[0] = array[i];
            array[i] = temp;
            // i 位置被占用,排序数组长度-1
            len--;
            maxHeap(array, 0, len);

            System.out.println(Arrays.toString(array));
        }
    }

Jaja, ¿el algoritmo se considera un principiante? Vamos, el próximo artículo "Algoritmo de clasificación rápido"

Supongo que te gusta

Origin blog.csdn.net/lijie2664989/article/details/83592500
Recomendado
Clasificación