@@ -168,4 +168,63 @@ public class MergeSort {
168
168
169
169
## 快速排序
170
170
171
- 快速排序也采用了分治的思想:把原始的数组筛选成较小和较大的两个子数组,然后递归地排序两个子数组。
171
+ 快速排序也采用了分治的思想:把原始的数组筛选成较小和较大的两个子数组,然后递归地排序两个子数组。
172
+
173
+ ### 代码示例
174
+
175
+ ``` java
176
+ import java.util.Arrays ;
177
+
178
+ public class QuickSort {
179
+
180
+ private static void quickSort (int [] nums ) {
181
+ quickSort(nums, 0 , nums. length - 1 );
182
+ }
183
+
184
+ private static void quickSort (int [] nums , int low , int high ) {
185
+ if (low >= high) {
186
+ return ;
187
+ }
188
+ int [] p = partition(nums, low, high);
189
+ quickSort(nums, low, p[0 ] - 1 );
190
+ quickSort(nums, p[0 ] + 1 , high);
191
+ }
192
+
193
+ private static int [] partition (int [] nums , int low , int high ) {
194
+ int less = low - 1 , more = high;
195
+ while (low < more) {
196
+ if (nums[low] < nums[high]) {
197
+ swap(nums, ++ less, low++ );
198
+ } else if (nums[low] > nums[high]) {
199
+ swap(nums, -- more, low);
200
+ } else {
201
+ ++ low;
202
+ }
203
+ }
204
+ swap(nums, more, high);
205
+ return new int [] {less + 1 , more};
206
+ }
207
+
208
+ private static void swap (int [] nums , int i , int j ) {
209
+ int t = nums[i];
210
+ nums[i] = nums[j];
211
+ nums[j] = t;
212
+ }
213
+
214
+ public static void main (String [] args ) {
215
+ int [] nums = {1 , 2 , 7 , 4 , 5 , 3 };
216
+ quickSort(nums);
217
+ System . out. println(Arrays . toString(nums));
218
+ }
219
+ }
220
+ ```
221
+
222
+ ### 算法分析
223
+
224
+ 空间复杂度 O(logn),时间复杂度 O(nlogn)。
225
+
226
+ 对于规模为 n 的问题,一共要进行 log(n) 次的切分,和基准值进行 n-1 次比较,n-1 次比较的时间复杂度是 O(n),所以快速排序的时间复杂度为 O(nlogn)。
227
+
228
+ 但是,如果每次在选择基准值的时候,都不幸地选择了子数组里的最大或最小值。即每次把把数组分成了两个更小长度的数组,其中一个长度为 1,另一个的长度是子数组的长度减 1。这样的算法复杂度变成 O(n²)。
229
+
230
+ 和归并排序不同,快速排序在每次递归的过程中,只需要开辟 O(1) 的存储空间来完成操作来实现对数组的修改;而递归次数为 logn,所以它的整体空间复杂度完全取决于压堆栈的次数。
0 commit comments