快速排序
常见的快速排序算法!Java版加了详细的注释,方便日后复习,也希望能帮到其他小伙伴,如有错误,欢迎指正!
Java实现:
class Solution {
public int[] sortArray(int[] nums) {
// 用快排对nums进行排序
quick_sort(nums,0,nums.length - 1);
return nums;
}
public void quick_sort(int[] nums,int left,int right){
// 快排的思想就是分治,不断把nums拆分成小的,直到拆成一个元素(right - left <= 0),递归就结束
if (right - left <= 0){
return;
}
// 对于每一次拆分,我们都需要找到一个中间值,将nums中比中间值小的放到中间值的左边,反之则不动,并且我们需要返回这个中间值的索引
int mid = right_partition(nums,left,right);
// 拆分后的左子数组和右子数组分别再递归快排
quick_sort(nums,left,mid - 1);
quick_sort(nums,mid + 1,right);
}
// 拆分时中间值的选取有很多种方法,比如选最左边、最右边、随机都可以,但是左边和随机都需要在遍历前换一次位置,比较麻烦,我习惯选最右边的元素
public int right_partition(int[] nums,int left,int right){
// 拆分的方法也很简单,先初始化一个中心点pivot,用来和其他的元素值作比较
int pivot = right;
// 初始化一个i,用来记录下一个小于pivot值的元素应该放在哪里,注意这里我们i最好设置为最左边的前一个,因为每一次需要后移;
// 设置为left - 1,第一次i++后就可以刚好在left的位置
int i = left - 1;
// 遍历,我们从最左边遍历到最右边的前一个,因为最后一个其实是中间值,不需要遍历
for (int j = left; j < right; j++){
// 如果遍历到的元素值小于中间点的值,说明该元素应该放在中间点的左边,我们就把这样的元素统一依次排在数组的前面
if (nums[j] < nums[pivot]){
i++;
swap(nums,i,j);
}
}
// 到这里说明数组已经将所有小于中间点的值的元素都放在数组的前面了,我们只需要把中间点放到这些元素的后面一个即可
i++;
swap(nums,i,pivot);
// 最后我们返回中间点最终的索引
return i;
}
// 交换数组中指定索引的两个元素
public void swap(int[] nums,int a,int b){
int tmp = nums[a];
nums[a] = nums[b];
nums[b] = tmp;
}
}
Python3实现(Python的实现思路和Java是一样的,几乎没区别):
class Solution:
def quick_sort(self,nums,left,right):
if right - left <= 0:
return
mid = self.right_partition(nums,left,right)
self.quick_sort(nums,left,mid - 1)
self.quick_sort(nums,mid + 1,right)
# 用了列表最右边的元素作为中间点
def right_partition(self,nums,left,right):
pivot = right
i = left - 1
for j in range(left,right):
if nums[j] < nums[pivot]:
i += 1
nums[i],nums[j] = nums[j],nums[i]
i += 1
nums[i],nums[pivot] = nums[pivot],nums[i]
return i
def sortArray(self, nums: List[int]) -> List[int]:
right = len(nums)
self.quick_sort(nums,0,right - 1);
return nums