算法原理
快速排序算法采用分而治之的方法来进行排序:
- 通过选择数组中的某个元素,比如最右边的元素,然后根据这个元素将数组切分成左右两个子数据;
- 切分数组的方式是,将比该元素小的元素放在该元素的左边,将比该元素大的元素放在其右边。切分后的左数组和右数组按同样的方法再切分,直到每个子数组只包含一个元素;
- 此时所有的元素已经排好序了,排序完成。
举例说明
比如,设有数组[8,7,6,1,0,9,2]
,按照元素2来切分数组,将比2小的元素放左边,比2大的元素放右边,即[1,0,2,8,7,9,6]
。
此时,数组被切分成[1,0]
和[8,7,9,6]
两个子数组,接下来需要将这两个子数组按同样方法进行切分。直到子数组只有一个元素时,排序完成。
但首先需要说明的是,对于每次切分数组的具体过程:
对于原数组:[8,7,6,1,0,9,2]
,首先需要一个指针a
(这里的指针即数组的下标)指向第一个元素8,然后另一个指针b
从第二个元素7开始遍历。如果找到一个比2小的元素,便让a
指向的元素与b
指向的元素交换位置。
所以,当指针b
遍历到元素1时,由于1比2小,所以交换位置,数组变为:[1,7,6,8,0,9,2]
。之后,a
指针右移一位,指向元素7,b
指针右移指向元素0。
因为0比2小,所以继续交换,数组变为:[1,0,6,8,7,9,2]
。
a
指针右移一位,指向元素6,b
指针继续遍历。当指针b
指向最后一个元素2时,将a
, b
指向的元素再交换位置。此时a
指针指向6,b
指针指向2。交换后数组为:[1,0,2,8,7,9,6]
。
对于切分后的数组,适合采用递归的方法再进行切分,直到排序完成。
代码实现
import java.util.Arrays;
public class Solution {
public static void main(String[] args) {
int[] nums = {8, 7, 6, 1, 0, 9, 2};
System.out.println("排序之前: " + Arrays.toString(nums));
int a = 0;
int b = nums.length - 1;
quicksort(nums, a, b);
System.out.println(Arrays.toString(nums));
}
private static void quicksort(int[] nums, int a, int b) {
if (a < b) {
int index = switchElement(nums, a, b);
System.out.println(index);
quicksort(nums, a, index - 1);
quicksort(nums, index + 1, b);
}
}
private static int switchElement(int[] nums, int a, int b) {
int element = nums[b]; // 选取最右侧的元素
int first = a; // 相当于指针a, 当交换位置后右移一位
for (int i = a + 1; i < b; i++) {
if (nums[i] < element) {
// 交换位置,nums[i]小于element, 所以交换位置
int temp = nums[i];
nums[i] = nums[first];
nums[first] = temp;
first++; // 指向最左侧的元素向右移动一位
System.out.println("交换一次后的数组: " + Arrays.toString(nums));
}
}
// 当指针b遍历指向element元素后, 再交换一次
int temp = nums[b];
nums[b] = nums[first];
nums[first] = temp;
System.out.println("交换一次后的数组: " + Arrays.toString(nums));
return first;
}
}
时间复杂度
待续