アルゴリズム(5)クイックソート

ソート原則

クイックソートはまた、分割統治として知られ、分割統治の戦略を使用します。原理は元の問題と同じ小さな問題、再帰的な解決の小さな問題の大きな問題に分解され、統合ソリューションの問題の解決策は、小さな問題で育ちました。クイックソートの主なアイデアは、ランダムにスカラー全体の左側にあること、それはそれはスカラーがそれを配置する必要がありますどのような位置に配置する必要があり、行の位置の良好な秩序を持つスカラー場から選択される少なく、標準量、スカラーの右よりですそれぞれ、よりすべてのスカラー大きく、上記スカラー処理ロジックアレイの両方の側面、このロジックを再帰的にこれまで順序付けられたすべての要素まで。
特定のプロセス:アレイを横断し、尾部から前方に横断しながら2つのミートアップだけ針、トラバーサル、ヘッドから後方にトラバースされるまで、ヘッドから後方にスカラーのランダム配列の最初のステップで開始しあなたは、比率のスカラ大きさの要素は、あなたが標準ストップよりも要素の大量、および記録素子が発生した場合、バック横断し、何もしないように続けて発生した場合は、尾前方トラバーサルからサイドしばらく、あなたは標準よりも要素が大量に発生した場合、何もしないし、あなたが遭遇した場合、彼らは2だけ針トラバース停止後に会った要素の意味におけるスカラ要素が停止され、この時だけ2針交換位置よりも小さい場合には、前方にトラバースし続けますインデックス位置及びスカラー検索配列に基づいて、インデックスに記録されるソートが完了した公知の上記の手順を繰り返し、2つの小さな問題に分割されます。

ここに画像を挿入説明

初めての複雑

2例に分けのクイックソートの時間計算

  • スカラーをランダムに選択し、アレイ内の最大値または最小値、O(N 2)の時間複雑されている場合。最初の配列内の要素の数はフロントソートされていない一つだけ少ない要素より分割されている場合、最初のサイクル、この場合、分割されたN-1回ので、i番目の分割長さは、実際には、N- I + 1、NI倍に必要な比較の数、比較の数が最大値N *に達するように、(N-1)/ 2 = O(N 2)。
  • 値のランダムに選択されたスカラー配列した場合、時間計算量はO(nlog2n)です。

ソートコード

package com.alg.sort;

import org.junit.Test;

import java.util.Random;

public class QuickSort {
    public void quickSort2(int[] a, int l, int r) {
        //递归终止判断,当标量已经是数组最后一位了,就该终止程序
        if (l >= r) {
            return;
        }
        int p = partition2(a, l, r);
        quickSort2(a, l, p);
        quickSort2(a, p + 1, r);
    }

    /**
     * 数组中重复元素过多导致快速排序的时间复杂度为O(n^2),
     * 优化方式为:选定一个标量,从数组的两头开始遍历分别遇到比变量大的或者比标量小的停止
     * 并交换两个停止位置元素的位置。
     */
    public int partition2(int[] arr, int l, int r) {
        int t = arr[l];
        //优化1:随机抽取数组中的元素作为标量,优化近乎有序的数组的快速排序
        Random random = new Random();
        int randomIndex = random.nextInt(r) % (r - l + 1) + l;
        arr[l] = arr[randomIndex];
        arr[randomIndex] = t;

        int v = arr[l];
        
        int i = l + 1;
        int j = r;

        while (true) {
            //从左往右遍历,该循环停止了,那么就遇到大于等于标量的元素了,边界的i要小于等于r,因为r是数组遍历技术的位置。
            while (i <= r && arr[i] < v) {
                i++;
            }
            //从右往左遍历,该循环停止了就遇到了小于等于标量的元素了,边界j要大于等l,不能比L小,因为L是数组排序开始的位置
            while (j >= l && arr[j] > v) {
                j--;
            }
            //当i和j相遇了,则没有元素需要遍历了
            if (i > j) {
                break;
            }
            //将大于等于标量和小于等于标量的元素进行位置交换,这样重复的元素就别分散到了元素的两边
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
        return j;
    }

公開された94元の記事 ウォン称賛55 ビュー110 000 +

おすすめ

転載: blog.csdn.net/Suubyy/article/details/100106199
おすすめ