クイックソートは
o(n^2)
、アルゴリズムの最悪の場合の時間の複雑さです。最悪の場合の時間の複雑さは劣りますが、平均的なパフォーマンスが非常に優れているため、実際の並べ替えアプリケーションでは通常、クイック並べ替えが最良の選択です。o(nlgn)
説明
マージソートと同様に、クイックソートアルゴリズムも除算と征服のアイデアを使用します。クイックソートの3つの除算と征服のプロセスは次のとおりです。
-
分解:配列パーティション。ここでは、最後の要素をパーティション標準として使用し、パーティションロジックを次の図に示します。
-
解決策:クイックソートを再帰的に呼び出して、左右の配列をソートします。
-
マージ:サブアレイはすべてその場でソートされるため、マージする必要はありません。
成し遂げる
配列パーティションの実装:最後の要素をパーティション化するサンプル要素として使用します。配列を左、中央(サンプル要素の保存領域)、および右の3つのグループに分割します。左側の領域は中央より小さく、右側の領域は中央より大きくなっています
/**
* 数组分区算法
* 以最后一个元素为样本元素,进行分区
* 将数组划分为左、中(样本元素存放区域)、右三组。左侧区域小于中,右侧区域大于中
*
* @param array 待排序数组
* @param start 数组开始位置
* @param end 数组结束位置
* @return 样本元素位置
*/
private static int partition(int[] array, int start, int end) {
int sample = array[end];
//默认左侧区域为空
int leftEnd = start - 1;
int temp;
for (int j = start; j < end; j++) {
//如果当前位置元素值小于样本值
if (array[j] <= sample) {
//将当前元素移动到左侧区域,即左侧区域空间增加1
leftEnd++;
temp = array[leftEnd];
array[leftEnd] = array[j];
array[j] = temp;
}
}
//将样本元素移动到中间区域,也就是与左侧区域紧挨着
//leftEnd + 1 就是样本元素所在位置
//如此形成左、中、右的区间排布
temp = array[leftEnd + 1];
array[leftEnd + 1] = array[end];
array[end] = temp;
//输出分区后的数组
System.out.println(Arrays.toString(array));
return leftEnd + 1;
}
並べ替えの実装:他の再帰呼び出しと大差ありません。サブ配列を並べ替えるたびにサンプル要素を削除する必要があることに注意してください。
/**
* 快速排序
* @param array 排序数组
* @param start 数组起始位置
* @param end 数组结束位置
*/
private static void quickSort(int[] array, int start, int end) {
if (start < end){
//对数组进行分区,记录分区后的样本元素位置点位置
int mid = partition(array,start,end);
//对样本元素左侧区域进行递归排序
quickSort(array,start,mid-1);
//对样本元素右侧区域进行递归排序
quickSort(array,mid+1,end);
}
}
この記事は予想より4日遅れて、忙しいスケジュールから「自由時間」で制作されました。品質は平均的で、価格は固執しています!みなさん、さあ、次の記事「線形時間ソートアルゴリズム」