Cuaderno de clasificación de basura de cien millones de niveles de 78 ms para lograr una clasificación de mil millones de niveles (parte 2)

No hay mucho que decir: los primeros resultados llaman la atención

consejo: para volúmenes de datos más grandes u otros entornos más exigentes, considere dividir y conquistar

Resultados de la prueba

El consumo de
Inserte la descripción de la imagen aquí
memoria que consume mucho tiempo :
configuración de computadora mínima (sin vmvare, se le ocurre la idea 4M)
Inserte la descripción de la imagen aquí

demanda

Cómo extraer los 100 números más grandes en el nivel de datos 1E.
Idea:
Use una lista individualmente vinculada ordenada personalizada para filtrar (aquí en orden ascendente)

  1. Para valores más pequeños que el valor más a la izquierda, descartar directamente sin ningún procesamiento
  2. Para valores mayores que el valor más a la derecha (máximo), la lista vinculada se desplaza hacia la derecha (es decir, se elimina el más a la izquierda y se agrega el más a la derecha)
  3. Para valores mayores que el valor más a la izquierda y menores que el valor máximo, el subíndice se desplaza hacia la derecha hasta que se encuentra un valor mayor que él,
  4. Para solo mayor que el valor más a la izquierda, cambie el valor directamente al valor más a la izquierda
  5. Para el valor medio (más grande que el valor más a la izquierda y más pequeño que el valor más a la derecha), asignamos el nodo más a la izquierda al valor e insertamos la
    idea central (se ha obtenido la posición 2) +
    para un volumen de datos de orden de magnitud mayor, Se puede adoptar la idea de divide y vencerás, por lo que teóricamente la idea puede manejar órdenes ilimitadas de datos.
package practice;

import java.util.*;

public class Main {
    
    
    class ListNode {
    
    
        int val;
        ListNode next;
        public ListNode() {
    
    
        }

        public ListNode(int val) {
    
    
            this.val = val;
        }
    }
    public ListNode createNode(int val){
    
    
        return new ListNode(val);
    }
    public static void main(String[] args) {
    
    
        Main main = new Main();
        int ti=0;
        //赋予1E个随机数字,用于排序
        int[] arr=new int[10000*10000];
        Random random=new Random();
        for (int i = 0; i < arr.length; i++) {
    
    
            arr[i]=random.nextInt();
        }
        //开始计时
        long start = System.currentTimeMillis();
        //抽取数组前100位并排序,用于初始化链表
        int[] ints = Arrays.copyOfRange(arr, 0, 100);
        Arrays.sort(ints);
        ListNode root=main.createNode(0);
        root.next=main.createNode(Integer.MIN_VALUE);
        ListNode curr=root.next;
        //记录最后一个
        ListNode last=curr;
        //初始化长度100的链表
        for (int i = 0; i < ints.length; i++) {
    
    
            curr.next=main.createNode(ints[i]);
            last=curr;
            curr=curr.next;
        }

        //筛除最大100个
        for (int i = 0; i < arr.length; i++) {
    
    
            curr=root.next;
            //比最左大才判断,否则直接舍弃
            if (arr[i]>curr.val) {
    
    
                //首先跟最右比较,比最右大
                if (arr[i] >= last.val) {
    
    
                    //是最大,删除最左,添加最右
                    root.next = root.next.next;
                    last.next = main.createNode(arr[i]);
                    last = last.next;
                } else {
    
    
                    //比最左边大,下标右移,直至右边比其大
                    while (curr.next != null && arr[i] > curr.next.val) {
    
    
                        curr = curr.next;
                    }
                    //右移完成
                    //处于最左边,最左边直接复制
                    if (curr.val==root.next.val) {
    
    
                        curr.val=arr[i];
                    }
                    //处于中间
                    else {
    
    
                        //增加新中间节点,废物利用,减少新对象的创建
                        ListNode node=root.next;
                        node.val=arr[i];
                        //删除最左节点
                        root.next = root.next.next;
                        //串联新增节点
                        node.next=curr.next;
                        curr.next=node;
                    }
                }
            }
        }
        //计时结束
        System.out.println("总计用时");
        System.out.println(System.currentTimeMillis()-start);
        //遍历,校验结果
        curr=root.next;
        while (curr!=null)
        {
    
    
            System.out.println(curr.val);
            curr=curr.next;
        }
    }
}



Supongo que te gusta

Origin blog.csdn.net/weixin_43158695/article/details/113199734
Recomendado
Clasificación