¿Será hoy el día de la oferta? ¿Realmente escribirás y ordenarás la entrevista?

UP tiene la intención de resolver los más difíciles de entender entre los ocho algoritmos de clasificación, que son la clasificación de fusión, la clasificación rápida y la clasificación de montón. Hoy presentaré la clasificación por fusión.

Inserte la descripción de la imagen aquí

Déjame hablar sobre el diagrama de tipo de fusión

Inserte la descripción de la imagen aquí
La llamada fusión es fusionar dos o más archivos ordenados en un nuevo archivo ordenado. La clasificación de fusión es tratar un archivo no ordenado con n registros como un orden con n longitudes de 1. El archivo compuesto por subarchivos se fusiona de dos en dos, y así sucesivamente, hasta que finalmente se forman n fusiones, y se obtienen n / 2 archivos ordenados con una longitud de 2 o 1, y luego se fusionan de dos en dos, y se repiten de esta manera hasta la inclusión final Hay n posiciones de archivo ordenadas grabadas. Este método de clasificación para fusionar repetidamente dos archivos ordenados en un archivo ordenado se denomina clasificación de fusión bidireccional.

Sin más preámbulos, solo ve directamente al código

import java.util.ArrayList;
import java.util.Arrays;

public class MergeSortTest {
    public static void main(String[] args) {
        int[] num = new int[]{12, 2, 3, 18, 9, 10, 21, 7, 6, 1, 23};
        System.out.println("需要排序的数组;" + Arrays.toString(num));
        MergeSort(num, 0, num.length - 1);
        System.out.println(Arrays.toString(num));
    }

    public static void MergeSort(int[] num, int left, int right) {
        int middle = (left + right) / 2;
        if (left >= right) {
            return;
        }
        MergeSort(num, left, middle);
        MergeSort(num, middle + 1, right);
        //注意这里
        Merge(num, left, middle, right);
        System.out.println(Arrays.toString(num));
    }

    public static void Merge(int[] num, int left, int middle, int right) {
        int[] num_copy = new int[right - left + 1];
        int left_copy = left;
        int right_copy = middle + 1;
        int index = 0;
        ///每次进行比较,把较小的数移入新数组
        while (left_copy <= middle && right_copy <= right) {
            if (num[left_copy] < num[right_copy]) {
                num_copy[index++] = num[left_copy++];
            } else {
                num_copy[index++] = num[right_copy++];
            }
        }
        //把左边剩余的数字移入数组
        while (left_copy <= middle) {
            num_copy[index++] = num[left_copy++];
        }
        //把右边剩余的数字移入数组
        while (right_copy <= right) {
            num_copy[index++] = num[right_copy++];
        }
        //覆盖旧数组
        for (int i = 0; i < num_copy.length; i++) {
            num[left + i] = num_copy[i];
        }
    }
}

Inserte la descripción de la imagen aquí

¿Se ve fácil? La clasificación de fusión incluye principalmente dos métodos. El primer método es MergeSort, que se usa para agrupar matrices, y el segundo método, Merge, se usa para fusionar dos matrices ordenadas.

Inserte la descripción de la imagen aquí

Hablar es fácil, muéstrame el código. A continuación, veamos un problema de algoritmo muy clásico. Podemos usar nuestro tipo de fusión para resolver.

Pregunta 23 de la red china de Leetcode, aquí puede usar el tipo de fusión que acabamos de aprender a resolver.

Inserte la descripción de la imagen aquí


public class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }
}

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists.length == 2) {
            return Merge(lists[0], lists[1]);
        }
        if (lists.length == 1) {
            return lists[0];
        }
        if (lists.length == 0) {
            return null;
        }
        int length = lists.length;
        ListNode[] node1 = new ListNode[length / 2];
        ListNode[] node2 = new ListNode[length - length / 2];
        int index = 0;
        //这里将lists拆分到两个数组中。
        for (; index < node1.length; index++) {
            node1[index] = lists[index];
        }
        for (int i = 0; i < node2.length; i++) {
            node2[i] = lists[i + length / 2];
        }
        ///同理继续将拆分的两个数组进行递归。
        ListNode result1 = mergeKLists(node1);
        ListNode result2 = mergeKLists(node2);
        //要注意这里,对两个数组进行合并。
        return Merge(result1, result2);
    }
    ///合并两个有序数组
    public ListNode Merge(ListNode node1, ListNode node2) {
        if (node1 == null) {
            return node2;
        }
        if (node2 == null) {
            return node1;
        }
        ListNode node3;
        ListNode node4;
        ///这里确定头结点,node4是我们需要返回的头结点,node3用于逐步向后添加节点。
        if (node1.val > node2.val) {
            node3 = node2;
            node4 = node2;
            node2 = node2.next;
        } else {
            node3 = node1;
            node4 = node1;
            node1 = node1.next;
        }
        ///比较排序构建链表
        while (node1 != null && node2 != null) {
            if (node1.val > node2.val) {
                node3.next = node2;
                node3 = node2;
                node2 = node2.next;
            } else {
                node3.next = node1;
                node3 = node1;
                node1 = node1.next;
            }
        }
        //node1可能不为空,还要继续添加判断
        while (node1 != null) {
            node3.next = node1;
            node3 = node1;
            node1 = node1.next;
        }
        //同理node2也可能不为空,要继续添加节点
        while (node2 != null) {
            node3.next = node2;
            node3 = node2;
            node2 = node2.next;
        }
        //返回我们的头结点
        return node4;

    }
}

El método MergeKLists aquí es similar al método MergeSort en nuestro código uno.

Inserte la descripción de la imagen aquí

Bueno, lo presentaré hoy, mañana escribiremos otro algoritmo de clasificación muy importante, la clasificación de montón.

Publicado cinco artículos originales · ganado elogios 3 · Vistas 4908

Supongo que te gusta

Origin blog.csdn.net/HZGuilty/article/details/105620343
Recomendado
Clasificación