Calcul rapide de tri d'un grand nombre de K

        Permettez-moi de parler de la conclusion, la version finale du code est le suivant:

public class KthNum {
    public static int k = 2;
    public static boolean bigK = false;

    public static void main(String[] args) {
        int arr[] = {3, 2, 3, 1, 7, 4, 5, 5, 6};
        int kNum = quickSort(arr);
        System.out.println("kNum=" + kNum);
    }

    public static int quickSort(int arr[]) {
        int length = arr.length;
        if (k <= 0 || k > length) throw new RuntimeException("K值不合理");
        int left = 0, right = length - 1;
        int p = -1;
        while (k != p + 1) {
            if (k < p + 1) {
                right = p - 1;
            } else if (k > p + 1) {
                left = p + 1;
            }
            p = partition(arr, left, right);
        }
        return arr[p];
    }

    public static int partition(int[] arr, int left, int right) {
        int pivot = arr[right];
        int sortIndex = left;
        for (int arrIndex = sortIndex; arrIndex < right; arrIndex++) {
            if (bigK ? arr[arrIndex] > pivot : arr[arrIndex] < pivot) {
                swap(arr, arrIndex, sortIndex);
                sortIndex++;
            }
        }
        swap(arr, sortIndex, right);
        return sortIndex;
    }

    public static void swap(int[] arr, int i, int j) {
        if (i == j) return;
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }


}

      Ou les anciennes règles, je vais me concentrer sur parler des idées, comment à la fin est de trouver ce code, s'il vous plaît lire.

       Familiar étudiants en ligne rapide savent, sinon familier avec les étudiants, je peux regarder cette langue vernaculaire résolu trier rapidement . vidange rapide à l' aide d' un numéro de partition en tant que point de référence, le point de référence est typiquement le nombre est inférieur à la partie gauche du point de référence, le point de référence à la droite du numéro est supérieur au point de référence.

        Cet ensemble de nombres tels que 1,3,4,2, en utilisant la ligne rapide avec 2 l' ordre inverse comme point de référence pour la première fois à la suite de 3,4,2,1, si vous arrive d'être à la recherche troisième plus grand nombre, il est point de référence 2, seule la première sorte, la complexité en temps est en O (n). Si vous cherchez un grand nombre de première ou deuxième plus grand nombre, puis continuer à la sorte compare à gauche du point de référence, si vous cherchez le quatrième plus grand nombre, puis trier le point de référence droite pour le comparer. les étudiants attentifs peuvent trouver un grand nombre de K-recherche, et la valeur de l' indice K est le point d'une relation de référence . Après l'achèvement du premier tri, le point de référence 2 de l'indice 2, l'utilisation d' indices +1 et K sont comparés, si K est égal à l'indice 1 renvoie directement la valeur courante de l'objet, si K est supérieur à l' indice 1 , continué pour trouver le point de référence de droite, si K est inférieur à l' indice +1 , continuer à regarder le côté gauche du point de référence. Trouvez des cycles jusqu'à ce que K est égal à l' indice 1 est terminé.

       Sur la base des idées ci-dessus et la compréhension de la ligne rapide, nous arrivons à calculer la première version K 1.0 de Tarse.

 1.0 :

public class KthNum {
    public static void main(String[] args) {
        int arr[] = {3, 2, 3, 1, 7, 4, 5, 5, 6};
        int k = 2;
//        k=4;
        int kNum = quickSort(arr, 0, arr.length - 1, k);
        System.out.println("kNum=" + kNum);

    }

    public static int quickSort(int arr[], int left, int right, int k) {
        if (left >= right) return -1;
        int p = partition(arr, left, right);
        while (k != p + 1) {
            if (k < p + 1) {
                p = partition(arr, left, p - 1);
            } else if (k > p + 1) {
                p = partition(arr, p + 1, right);
            }
        }
        return arr[p];
    }

    public static int partition(int[] arr, int left, int right) {
        int pivot = arr[right];
        int sortIndex = left;
        for (int arrIndex = sortIndex; arrIndex < right; arrIndex++) {
            if (arr[arrIndex] > pivot) {
                swap(arr, arrIndex, sortIndex);
                sortIndex++;
            }
        }
        swap(arr, sortIndex, right);
        return sortIndex;
    }

    public static void swap(int[] arr, int i, int j) {
        if (i == j) return;
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
}

Dans le code ci-dessus est K 2, il peut être déterminé correctement pour le deuxième numéro 6,. Mais quand K est 4, une boucle infinie se produit.

Alors, pourquoi boucle infinie se produit:

1 idée:

Un examen plus approfondi du code en boucle si et si d'autre et d'analyser son processus de mise en œuvre est la suivante:

La figure est une cloison arrière en oeuvre du procédé à chaque fois, la position du point de référence de l' indice p. En analysant les résultats des 9 et 14, vous pouvez savoir si elle continuera à descendre dans la boucle 9-13 fois. Ont maintenant trouvé le problème, quelle est la cause du problème?

2 problèmes causés par:

     1. tandis que la valeur de boucle à gauche et à droite ont été aucune modification ne peut

     2. Résultats de l'analyse de 8 fois, se trouvent deux valeurs identiques 5 l'échange de données ne se produit pas dans la comparaison, ce qui aboutit à la première 7, 6, 5, 4, 5, 3, 3, 2, 1 le numéro du numéro 4 et 5 ne peuvent pas former des positions commandées.

2 idées:

      Comparative tandis que le code de la boucle et le code trouveront ligne rapide, la valeur de la gauche et la droite n'a pas changé dans le cycle. Selon les estimations préliminaires peuvent conduire à a été classé numéro au cours du prochain cycle continuera de participer à l'ordre de tri, ce qui entraîne dans une boucle infinie.

1.0 Résumé:

Je veux surtout réaliser rapidement le grand nombre de programmes K en copiant et collant le chemin, mène à la mort attitude paresseuse des problèmes circulatoires dans cette version

 1.1 :

· Boucle infinie résoudre le problème dans la version 1.0:

public class KthNum {
    public static void main(String[] args) {
        int arr[] = {3, 2, 3, 1, 7, 4, 5, 5, 6};
        int k = 2;
        k=4;
        int kNum = quickSort(arr, 0, arr.length - 1, k);
        System.out.println("kNum=" + kNum);

    }

    public static int quickSort(int arr[], int left, int right, int k) {
        if (left >= right) return -1;
        int p = partition(arr, left, right);
        while (k != p + 1) {
            if (k < p + 1) {
                p = partition(arr, left, p - 1);
            } else if (k > p + 1) {
                p = partition(arr, p + 1, right);
            }
        }
        return arr[p];
    }

    public static int partition(int[] arr, int left, int right) {
        int pivot = arr[right];
        int sortIndex = left;
        for (int arrIndex = sortIndex; arrIndex < right; arrIndex++) {
            if (arr[arrIndex] >= pivot) {
                swap(arr, arrIndex, sortIndex);
                sortIndex++;
            }
        }
        swap(arr, sortIndex, right);
        return sortIndex;
    }

    public static void swap(int[] arr, int i, int j) {
        if (i == j) return;
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }


}

Procédé modifié la partition de code ligne 4, à partir arr [tindex]> pivot Modifier  ARR [tindex]> = Pivot . Il est égal à 2 quand peut encore être comparé le nombre de l'échange de données.

 2.0 :

· Réparation la version en boucle 1.0 de la valeur de gauche et à droite ont été aucune modification ne peut conduisant à un problème de boucle infinie, mais aussi notre ligne principale:

public class KthNum {
    public static void main(String[] args) {
        int arr[] = {3, 2, 3, 1, 7, 4, 5, 5, 6};
        int k = 2;
        k=4;
        int kNum = quickSort(arr, 0, arr.length - 1, k);
        System.out.println("kNum=" + kNum);

    }

    public static int quickSort(int arr[], int left, int right, int k) {
        if (left >= right) return -1;
        int p = partition(arr, left, right);
        while (k != p + 1) {
            if(k<p+1){
                right=p-1;
            }else if(k>p+1){
                left=p+1;
            }
            p=partition(arr,left,right);
        }
        return arr[p];
    }

    public static int partition(int[] arr, int left, int right) {
        int pivot = arr[right];
        int sortIndex = left;
        for (int arrIndex = sortIndex; arrIndex < right; arrIndex++) {
            if (arr[arrIndex] > pivot) {
                swap(arr, arrIndex, sortIndex);
                sortIndex++;
            }
        }
        swap(arr, sortIndex, right);
        return sortIndex;
    }

    public static void swap(int[] arr, int i, int j) {
        if (i == j) return;
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }


}

Modifier le code QuickSort ligne de traitement 5 et la ligne 7, le procédé de séparation tandis que les appels en boucle placés si à l'extérieur, pour modifier la valeur à gauche et à droite de l'autre si et si, donc en utilisant le calcul de décharge rapide K large nombre essentiellement réalisé.

3.0:

Cette version est optimisée pour la version 2.0:

public class KthNum {
    public static void main(String[] args) {
        int arr[] = {3, 2, 3, 1, 7, 4, 5, 5, 6};
        int k = 2;
        k=4;
        int kNum = quickSort(arr, 0, arr.length - 1, k);
        System.out.println("kNum=" + kNum);
    }

    public static int quickSort(int arr[], int left, int right, int k) {
        if (left >= right) return -1;
        int p=-1;
        while (k != p + 1) {
            if(k<p+1){
                right=p-1;
            }else if(k>p+1){
                left=p+1;
            }
            p=partition(arr,left,right);
        }
        return arr[p];
    }

    public static int partition(int[] arr, int left, int right) {
        int pivot = arr[right];
        int sortIndex = left;
        for (int arrIndex = sortIndex; arrIndex < right; arrIndex++) {
            if (arr[arrIndex] > pivot) {
                swap(arr, arrIndex, sortIndex);
                sortIndex++;
            }
        }
        swap(arr, sortIndex, right);
        return sortIndex;
    }

    public static void swap(int[] arr, int i, int j) {
        if (i == j) return;
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }


}

Modifié le code méthode QuickSort dans la deuxième rangée, l'idée est ici à la ligne 2 méthodes QuickSort et 9 rangs méthode appelée partition, je l'espère, ils peuvent être unifiés, donc j'affecté à p -1, l'unité appeler la méthode de séparation tandis que la boucle.

4.0:

Cette version est la version 3.0 de l'ajustement et l'optimisation:

public class KthNum {
    public static int k = 4;

    public static void main(String[] args) {
        int arr[] = {3, 2, 3, 1, 7, 4, 5, 5, 6};
        int kNum = quickSort(arr);
        System.out.println("kNum=" + kNum);
    }

    public static int quickSort(int arr[]) {
        int length = arr.length;
        if (k <= 0 || k > length) throw new RuntimeException("K值不合理");
        int left = 0, right = length - 1;
        int p = -1;
        while (k != p + 1) {
            if (k < p + 1) {
                right = p - 1;
            } else if (k > p + 1) {
                left = p + 1;
            }
            p = partition(arr, left, right);
        }
        return arr[p];
    }

    public static int partition(int[] arr, int left, int right) {
        int pivot = arr[right];
        int sortIndex = left;
        for (int arrIndex = sortIndex; arrIndex < right; arrIndex++) {
            if (arr[arrIndex] > pivot) {
                swap(arr, arrIndex, sortIndex);
                sortIndex++;
            }
        }
        swap(arr, sortIndex, right);
        return sortIndex;
    }

    public static void swap(int[] arr, int i, int j) {
        if (i == j) return;
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }


}

points d'optimisation:

    1. Les paramètres locaux internes des méthodes d'attribution de la méthode QuickSort droite et à gauche dans

    2. Retirer la méthode comparative QuickSort originale de gauche et à droite

    3. QuickSort ajouté procédé raisonnable de détermination de la valeur de K

4.0 Résumé pensée divergente:

       Jusqu'à présent, le calcul rapide ligne K grand nombre est terminée. Nous pensons toujours de divergence, car un grand nombre de K, puis trouver il y a certainement un petit nombre de besoins K. Avec ce numéro, nous re-regarder le code ci-dessus 4.0, vous pouvez dessiner deux types de programmes:

       1. Depuis la demande d'un grand nombre de K + 1 peut trouver différentes sortes d'intervalles de gamme en boucle et la K P. Alors même, trouver un petit nombre de K peut être calculé par la relation entre K et P.

       2. La méthode de partition ci-dessus est de trouver un grand nombre de K par manière inverse, puis le K-ième petit nombre qui cherchent seulement doivent ordre croissant.

4.1:

Cette version est la première K chercher un petit nombre d'un type de solution dans 4.0 Résumé:

public class KthNum {
    public static int k = 3;
    public static boolean bigK = false;

    public static void main(String[] args) {
        int arr[] = {3, 2, 3, 1, 7, 4, 5, 5, 6};
        int kNum = quickSort(arr);
        System.out.println("kNum=" + kNum);
    }

    public static int quickSort(int arr[]) {
        int length = arr.length;
        if (k <= 0 || k > length) throw new RuntimeException("K值不合理");
        int left = 0, right = length - 1;
        int p = bigK ? -1 : partition(arr, left, right);
        while (k != (bigK ? p + 1 : length - p)) {
            if (bigK ? k < p + 1 : k > length - p) {
                right = p - 1;
            } else if (bigK ? k > p + 1 : k < length - p) {
                left = p + 1;
            }
            p = partition(arr, left, right);
        }
        return arr[p];
    }

    public static int partition(int[] arr, int left, int right) {
        int pivot = arr[right];
        int sortIndex = left;
        for (int arrIndex = sortIndex; arrIndex < right; arrIndex++) {
            if (arr[arrIndex] > pivot) {
                swap(arr, arrIndex, sortIndex);
                sortIndex++;
            }
        }
        swap(arr, sortIndex, right);
        return sortIndex;
    }

    public static void swap(int[] arr, int i, int j) {
        if (i == j) return;
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }


}

Code des changements impliquant une comparaison de la relation entre K et P, est une pensée à contre-courant. A la recherche du nombre de chaîne inverse dans un petit nombre de K, par exemple, 7, 6, 5, 5, 4, 3, 3, 2, 1 dans le groupe 6 est un second nombre de grands nombres, les 8 premières heures nombre. regard intéressé de la boîte, mais la principale recommandation de la version 5.0 de la mise en œuvre.

5.0:

Cette version est le désir du petit K les 2 premières solutions 4.0 Résumé du nombre de:

public class KthNum {
    public static int k = 2;
    public static boolean bigK = false;

    public static void main(String[] args) {
        int arr[] = {3, 2, 3, 1, 7, 4, 5, 5, 6};
        int kNum = quickSort(arr);
        System.out.println("kNum=" + kNum);
    }

    public static int quickSort(int arr[]) {
        int length = arr.length;
        if (k <= 0 || k > length) throw new RuntimeException("K值不合理");
        int left = 0, right = length - 1;
        int p = -1;
        while (k != p + 1) {
            if (k < p + 1) {
                right = p - 1;
            } else if (k > p + 1) {
                left = p + 1;
            }
            p = partition(arr, left, right);
        }
        return arr[p];
    }

    public static int partition(int[] arr, int left, int right) {
        int pivot = arr[right];
        int sortIndex = left;
        for (int arrIndex = sortIndex; arrIndex < right; arrIndex++) {
            if (bigK ? arr[arrIndex] > pivot : arr[arrIndex] < pivot) {
                swap(arr, arrIndex, sortIndex);
                sortIndex++;
            }
        }
        swap(arr, sortIndex, right);
        return sortIndex;
    }

    public static void swap(int[] arr, int i, int j) {
        if (i == j) return;
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }


}

ajouter ici une variable membre bigK faire identité: aux vrais représentants qui cherchent un grand nombre de K, false chercher au nom d'un petit nombre de K . Alors que dans la quatrième méthode de ligne de partition apporte également des modifications: bigK Si cela est vrai, l'utilisation de la marche arrière, bigK si elle est fausse, puis ascendantes employé. Ce minimum les changements nécessaires pour atteindre les exigences du grand nombre de K et un petit nombre de K, parfait.

 

Publié 25 articles originaux · louange gagné 51 · vues 20000 +

Je suppose que tu aimes

Origine blog.csdn.net/Royal_lr/article/details/105074745
conseillé
Classement