前言
校招已经如火如荼的进行起来了,手撕代码是今年面试考察的重头戏。
按脉脉上的说法,左手一个快速排序,右手一个二叉树遍历,基本可以拦住一大半算法面试者了。
今天来梳理一下快速排序的知识点。
快排的思想
快排的思想大部分同学应该都能说的清楚。
快速排序是一个基于分治法的原地排序算法,每次以数组中某一个值作为基准,将比基准小的放到左侧,比基准大的放到右侧,就完成了一次排序;接下来分别对左右子数组进行快排,循环往复,就得到了有序的序列。
关于partition
partition是快速排序的核心函数。
关于partition的写法有很多种,在此给出一种官方版本(来自算法导论第二版)。
其中A是数组,p和r分别是数组的前后指针。
令最后一个元素作为基准,指针i记录小于基准的元素边界,指针j动态去扫描小于基准的元素,若扫描到,则使指针i扩张,并将元素交换至i,继而保持i指针记录小于基准的元素边界。
指针j完成扫描后,将基准交换到边界(i+1),完成一轮partition,返回基准下标。
Java快速排序实现
恰巧leetcode上也有一个提交排序算法的题目,本文使用了java对上述思路进行了实现。
leetcode地址为:https://leetcode-cn.com/problems/sort-an-array/
没有使用1.8的新feature,cpp的同学应该也可以清晰看懂。
代码如下:
class Solution {
public int[] sortArray(int[] nums) {
quickSort(nums,0,nums.length-1);
return nums;
}
public void quickSort(int[] nums,int low,int high){
if(low > high) return;
int mid = partition(nums,low,high);
quickSort(nums,low,mid-1);
quickSort(nums,mid+1,high);
}
public int partition(int[] nums,int low,int high){
int x = nums[high];
int i = low-1;
for(int j = low;j<high;j++){
if(nums[j] <=x){
i++;
swap(nums,i,j);
}
}
swap(nums,i+1,high);
return i+1;
}
public void swap(int[] nums,int i ,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}