面試攔路虎之快速排序

前言

校招已經如火如荼的進行起來了,手撕代碼是今年面試考察的重頭戲。
按脈脈上的說法,左手一個快速排序,右手一個二叉樹遍歷,基本可以攔住一大半算法面試者了。
今天來梳理一下快速排序的知識點。

快排的思想

快排的思想大部分同學應該都能說的清楚。
快速排序是一個基於分治法的原地排序算法,每次以數組中某一個值作爲基準,將比基準小的放到左側,比基準大的放到右側,就完成了一次排序;接下來分別對左右子數組進行快排,循環往復,就得到了有序的序列。

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