演算法導論學習之五:快速排序

趙明威發表於2016-04-09

一、原理介紹

快速排序由於排序效率在同為O(N*logN)的幾種排序方法中效率較高,因此經常被採用,再加上快速排序思想----分治法也確實實用,因此很多軟體公司的筆試面試,包括像騰訊,微軟等知名IT公司都喜歡考這個,還有大大小的程式方面的考試如軟考,考研中也常常出現快速排序的身影。

總的說來,要直接默寫出快速排序還是有一定難度的,因為本人就自己的理解對快速排序作了下白話解釋,希望對大家理解有幫助,達到快速排序,快速搞定。

快速排序是C.R.A.Hoare於1962年提出的一種劃分交換排序。它採用了一種分治的策略,通常稱其為分治法(Divide-and-ConquerMethod)。

該方法的基本思想是:

1.先從數列中取出一個數作為基準數。

2.分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。

3.再對左右區間重複第二步,直到各區間只有一個數。

雖然快速排序稱為分治法,但分治法這三個字顯然無法很好的概括快速排序的全部步驟。因此我的對快速排序作了進一步的說明:挖坑填數+分治法:

package sort;

import java.util.Arrays;
import java.util.Scanner;

/**
 *還是一貫的不解釋,歡迎吐槽,找出錯誤繼續優化
 * Created by zhaomingwei on 16/4/8.
 */
public class QuickSortTest {

public static int count = 0;

public static void main(String[] args) {

    int[] b = {36, 24, 76, 11, 45, 64, 21, 69, 19, 36};
    quickSort(b,0,b.length-1);

    System.out.println("交換次數:"+count);

}

public static void quickSort(int a[], int left, int right){
    int i = left;
    int j = right;
    if (j <= i){
        return;
    }
    double key = (a[i]+a[j])/2.0;
    while(j > i){
        while(a[j] >= key && j > i){
            j --;
        }
        while(a[i] <= key && j > i){
            i ++;
        }

        if (j > i){
            int temp = a[i];
            a[i] = a[j];
            a[j] = temp;
            count ++;
        }
    }

    //toRemove
    System.out.println(Arrays.toString(a));

    quickSort(a,left,i);
    quickSort(a,j+1,right);
}
}

根據演算法第四版,感覺是比較簡潔的:

import java.util.Arrays;

/**
 * @author zhaomingwei
 * 快速排序
 */
public class QuickSort extends BaseMethod {
    public static void sort(Comparable[] a, int lo, int hi) {
        if (lo >= hi) {
            return;
        }
        /*k已經是排定的了*/
        int k = partition(a, lo, hi);
        sort(a, lo, k-1);
        sort(a, k+1, hi);
    }

    /**
     * 切分
     *
     * @return
     */
    public static int partition(Comparable[] a, int lo, int hi) {
        int i = lo;
        int j = hi+1;
        Comparable v = a[lo];
        while (i < j) {
            while (less(a[++i], v)) {
                if (i == hi) {
                    break;
                }
            }
            while (less(v, a[--j])) {
                if (j == lo) {
                    break;
                }
            }
            if (i >= j) {
                break;
            }
            exchange(a, i, j);
        }
        exchange(a, lo, j);
        return j;
    }

    public static void main(String[] args) {
        Integer[] a = {2, 3, 1, 8, 0, 5, 4, 6, 9, 7};
        sort(a, 0, a.length-1);
        System.out.println(Arrays.toString(a));
    }
}

相關文章