面试拦路虎之快速排序

前言

校招已经如火如荼的进行起来了,手撕代码是今年面试考察的重头戏。
按脉脉上的说法,左手一个快速排序,右手一个二叉树遍历,基本可以拦住一大半算法面试者了。
今天来梳理一下快速排序的知识点。

快排的思想

快排的思想大部分同学应该都能说的清楚。
快速排序是一个基于分治法的原地排序算法,每次以数组中某一个值作为基准,将比基准小的放到左侧,比基准大的放到右侧,就完成了一次排序;接下来分别对左右子数组进行快排,循环往复,就得到了有序的序列。

关于partition

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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章