インタビューサイト:細切り高速ソートアルゴリズム

アルゴリズムの概要

クイックソートとしても知られている(クイックソート)、分割交換ソートは、呼ばれる高速行を最初アントニー・ホーアによって提案されたソートアルゴリズムを、。平均的な条件下で、比較(Nログn)O n個のアイテムをソートします。最悪の状況では、O(N ^ 2)比較する必要がありますが、この状況は珍しいことではありません。

実際には、クイックソートのO(nはn個のログ)他のアルゴリズムよりも一般的にかなり速く、その内側のループは、ほとんどのアーキテクチャに到達するのに有効であること可能性があるため。

アルゴリズムのプロセス

クイックソート使用して分割を統治小さく、大きく二つのサブシーケンスのシーケンスに配置する戦略を、次いでソート再帰的に二つの配列。

ステップ:

  1. 選択基準値:一連の要素を選択し、「基準」(ピボット)と呼ばれます、
  2. セグメンテーション:並べ替え列、基準値よりも小さい全ては、参照の背後に配置された基準値要素より大きいすべて(基準値に等しい側の任意の数とすることができる)、基準要素の前に配置されます。このスプリットの終了後、基準値の並べ替えが完了しています、
  3. 再帰ソート順序:再帰的に参照配列要素は、要素の順序付けられたシーケンスの基準値よりも大きい場合より小さい値に。

最下位再帰決意条件は、列の数が明らかに順序付けられ、その時点で列の数またはゼロのサイズ、です。

具体的な方法のいくつかの種類の選択基準値は、この選択方法は、注文時のパフォーマンスに決定的な影響を持っています。

クイックソート・コード・ロジックは、次のように表すことができます。

public void quick(int arr, int head, int tail) {
    /*
    * 1.递归终止条件
    * 2.定义头尾指针与基准值
    * 2.把小于基准数的移到左边,把大于基准数的移到右边
    */
    quick(arr, head, right); //继续处理左边的
    quick(arr, left, tail); //继续处理右边的
}

サンプルコード

public class QuickSort {
  
    public static void qSort(int[] arr, int head, int tail) {
        if (head >= tail || arr == null || arr.length <= 1) {
            return;
        }
        //定义俩指针 用于移动
        int left = head;
        int right = tail;
        int pivot = arr[head]; //基准值,也可以arr[(head + tail) / 2]

        while (left <= right) {
            while (arr[left] < pivot) { //左指针先走,找到大于等于基准数的停止
                ++left;
            }
            while (arr[right] > pivot) { //右指针后走,找到小于等于基准数的停止
                --right;
            }
            if (left < right) {
                //交换arr[left]和arr[right]的位置
                int t = arr[left];
                arr[left] = arr[right];
                arr[right] = t;
                //继续遍历
                ++left;
                --right;
            } else if (left == right) {
                //遍历完,错开两指针
                ++left;
                //break;
            }
        }

        qSort(arr, head, right);
        qSort(arr, left, tail);
    }

    public static void main(String[] args) {
        int[] arr = new int[]{6, 1, 2, 7, 9, 3, 4, 5, 10, 8};
        qSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
  
}

プリントアウト:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

プログラム動作では、プロセスは、プリント枚数が注文する前に観察され、ソートされたカラムに通してもよいです

对数组 [6 1 2 7 9 3 4 5 10 8 ] 排序, 排序后 [5 1 2 4 3 9 7 (6) 10 8 ] 
对数组 [5 1 2 4 3 ] 排序, 排序后 [3 1 2 4 (5) 9 7 6 10 8 ] 
对数组 [3 1 2 4 ] 排序, 排序后 [2 1 (3) 4 5 9 7 6 10 8 ] 
对数组 [2 1 ] 排序, 排序后 [1 (2) 3 4 5 9 7 6 10 8 ] 
对数组 [3 4 ] 排序, 排序后 [1 2 (3) 4 5 9 7 6 10 8 ] 
对数组 [9 7 6 10 8 ] 排序, 排序后 [1 2 3 4 5 8 7 6 10 (9) ] 
对数组 [8 7 6 ] 排序, 排序后 [1 2 3 4 5 6 7 (8) 10 9 ] 
对数组 [6 7 ] 排序, 排序后 [1 2 3 4 5 (6) 7 8 10 9 ] 
对数组 [10 9 ] 排序, 排序后 [1 2 3 4 5 6 7 8 9 (10) ] 

複雑性分析

時間複雑

アレイは、第二の場合、この時間ならば、第一層は、n / 2であり、n / 2、ことを理解した上で、再帰呼び出しの半分と左半分部分次いで、有するn個の要素による再帰的計算に、支点の位置を算出します層は、N / 4、N / 4であり、 N / 4、N / 4 が理解される四つの部分、すなわち、n個の要素その層の合計2 ^ N =のK = K (n)はLOG2を次いでそれぞれNの複雑さは、その後平均であるO(nlog2 n)が時間の複雑。あなたは、標準例一種であれば、すでに昇順で、その後、再帰の右半分のみが存在する場合しかし、これは確かに平均的なケースである、、、左半分が除去されています。(N - 1)(Nは- 2) ... 1 *、これは確かに複雑であり、O(2 ^ N-)

宇宙複雑

高速放電は、再帰呼び出しを実現し、各関数呼び出しのみ空間定数を使用して、再帰深度の空間的な複雑さに等しくなります。

最高の状況はO(のlog2 n)はほとんどの時間で、ネストされた再帰呼び出しを必要とし、それが必要とO(のlog2 n)のスペースを。それが必要な、ネストされた再帰呼び出しの最悪の場合のO(N)時間を要するO(N)スペース。

ほとんどの基準時間の複雑さを知ります

https://www.zhihu.com/question/22393997/answer/189896378

おすすめ

転載: www.cnblogs.com/yueshutong/p/11369126.html