Java數據結構與算法——快速排序

聲明:碼字不易,轉載請註明出處,歡迎文章下方討論交流。

前言:Java數據結構與算法專題會不定時更新,歡迎各位讀者監督。本篇文章介紹排序算法中最經常使用也是面試中最容易考到的排序算法——快排,包括快排的思想和原理、java快排代碼、快排的特色性能和快排的適用場景。java

0、其餘排序算法索引(待更)

java數據結構與算法——桶排序
java數據結構與算法——插入排序面試

一、快速排序思想及原理

事實上,快速排序是堆冒泡排序的一種改進。算法

它的基本思想是:經過一趟排序將要排序的數據分割爲兩部分,第一部分全部數據比第二部分的全部數據小,按照這種思路將兩部分數據再次分別進行快速排序,可使用遞歸完成,最終使得整個數據序列有序。segmentfault

具體來說,在待排數據中找一個基準數據(一般取第一個數),接下來將待排數據中比基準數據小的放在待排數據的左側,將比待排數據中比基準數據大的放在待排數據右側。此時,左右兩個分區的元素相對有序,接着採用上述思路繼續對左右兩個分區繼續排序,直到各分區只有一個元素位置。這裏用到了一個典型的分治思想。下面舉例說明:數據結構

待排序列依次爲4七、2九、7一、9九、7八、1九、2四、47。爲了區分兩個47,將後面的47下面增長一個下劃線。性能

步驟:
一、選取一個基準數,通常選第0個元素47。
二、將比基準數小的移動到左側,比基準數大的移動到右側,相等的不移動,此時基準數位置爲K。
三、對左右兩側重複步驟1和步驟2,直到左右側細分到只有一個元素。測試

快排的難點也就是在第2步,怎麼移動各個數據?
<1> 首先從數列的右邊開始往左找,設下標爲i,也就是i--操做,找到第一個比基準數小的值,讓他與基準數交換;
<2> 接着開始從左往右找,設下標爲j,也就是j++,找到第一個比基準數大的值,讓他與基準數交換位置;
<3> 重複1和2,直到i和j相遇時結束,最後基準值所在位置爲k。ui

二、java快排代碼

public class QuickSort {
    private int[] array;
    public QuickSort(int[] array){
        this.array = array;
    }
    
    public void printSort(){
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }
    
    public void sort(){
        quicksort(array,0,array.length -1);
    }
    
    private void quicksort(int[] array,int begin,int end){
        if(begin<end){  //i和j沒相遇以前比較各數據與基準值大小
            int base = array[begin];  //取第一個值爲基準值
            int i = begin;  //左標記爲i
            int j = end;    //右標記爲j
            
            //一趟排序,找到比基準值大的在基準值右,比基準值小的在基準值左
            while(i<j){
                //從右往左掃描
                while(i<j && array[j]>base){ //從右往左掃,若是元素比基準值大
                    j--;  //則右邊標記--,直到找到第一個比基準值小的,中止掃描
                }
                if(i<j){
                    array[i]=array[j];  //交換右掃描第一個比基準值小的數
                    i++;  //i標記右移一位
                }
                //從左往右掃描
                while(i<j && array[i]<base){//從左往右掃,若是元素比基準值小
                    i++;  //則左標記++,直到找到第一個比基準值大的,中止掃描
                }
                if(i<j){
                    array[j]=array[i];  //交換左掃描第一個比基準值大的數
                    j--;  //j標記左移一位
                }
            }  //此時基準值左右兩側相對有序
            
            array[i] = base;  //此時i爲中間位置k
            
            quicksort(array,begin,i-1);  //左側按照快排思路,遞歸
            
            quicksort(array,i+1,end);    //右側按照快排思路,遞歸
        }
    }    
}

測試代碼this

public class SortTest {
    public static void main(String[] args) {
        teseQuickSort();
    }

    private static void teseQuickSort(){
        int[] array = {3,5,7,3,8,9,6,1,0};
        QuickSort qs = new QuickSort(array);
        qs.sort();
        qs.printSort();
    }
}

三、快排的特色及性能

快排是在冒泡排序之上改進而來的,冒泡排序每次只能交換相鄰的兩個元素,而快排則是跳躍式的交換,交換距離很大,總的比較次數和交換次數少了不少,速度也快了不少。code

快排的平均時間複雜度爲O(nlogn),事實上,大多數狀況下,排序速度要快於這個時間複雜度。快排其實是採用的一種分而治之的思想,把問題分解爲一個個的小問題去逐一解決,最終在把結果組合起來。

快排由於遞歸調用,因此空間複雜度爲O(logn)。

快排是一種不穩定的排序算法,在通過排序後,等值的元素的相對位置可能發生改變。

快排基本上被認爲是相同數量級中全部排序算法中平均性能最好的。

四、快排的適用場景

快排因爲相對簡單並且性能不錯,因此快排適用於幾乎絕大多數場合。

其餘排序算法索引(待更)
java數據結構與算法——桶排序
java數據結構與算法——插入排序

碼字不易,如對您有幫助,歡迎點贊收藏打賞^_^

相關文章
相關標籤/搜索