アルゴリズムの概要
クイックソートとしても知られている(クイックソート)、分割交換ソートは、呼ばれる高速行を最初アントニー・ホーアによって提案されたソートアルゴリズムを、。平均的な条件下で、比較(Nログn)O n個のアイテムをソートします。最悪の状況では、O(N ^ 2)比較する必要がありますが、この状況は珍しいことではありません。
実際には、クイックソートのO(nはn個のログ)他のアルゴリズムよりも一般的にかなり速く、その内側のループは、ほとんどのアーキテクチャに到達するのに有効であること可能性があるため。
アルゴリズムのプロセス
クイックソート使用して分割を統治小さく、大きく二つのサブシーケンスのシーケンスに配置する戦略を、次いでソート再帰的に二つの配列。
ステップ:
- 選択基準値:一連の要素を選択し、「基準」(ピボット)と呼ばれます、
- セグメンテーション:並べ替え列、基準値よりも小さい全ては、参照の背後に配置された基準値要素より大きいすべて(基準値に等しい側の任意の数とすることができる)、基準要素の前に配置されます。このスプリットの終了後、基準値の並べ替えが完了しています、
- 再帰ソート順序:再帰的に参照配列要素は、要素の順序付けられたシーケンスの基準値よりも大きい場合より小さい値に。
最下位再帰決意条件は、列の数が明らかに順序付けられ、その時点で列の数またはゼロのサイズ、です。
具体的な方法のいくつかの種類の選択基準値は、この選択方法は、注文時のパフォーマンスに決定的な影響を持っています。
クイックソート・コード・ロジックは、次のように表すことができます。
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)スペース。
ほとんどの基準時間の複雑さを知ります