Go語言實現(xiàn)快排+隨機快排

快排算法是一種本地算法,(即不需要額外的內存空間,就地排序)

  • 基本思想:
    從這個數(shù)列里找一個數(shù)作為基準點(支點)跟其它的數(shù)進行對比,小于或等于這個支點數(shù)的都放到左邊,大的放到右邊。完成一次排序,然后依次遞歸,當起始下標和末尾下標相遇是,排序結束,即整列數(shù)已經(jīng)排列好了順序。
  • 快排為什么快呢?
    簡單的總結是:快排實現(xiàn)了最優(yōu)下界。比如著名的稱球問題12個小球有一個是壞的(輕或重), 現(xiàn)在呢有一架天平,問最少可用多少次就能確定哪個小球是壞的,并且指出它是輕了還是重了。答案是三次,稱三次就能得出結論。等概率最優(yōu)。時間復雜度為O(nlgn)(n乘以以10為底n的對數(shù))
  • 快排為什么好像不那么快呢?
    當輸入的數(shù)列是一個已經(jīng)排序好的數(shù)列時(順序或逆序),就慢了,因為它無法找到一個支點是兩邊等分的,無法做到等概率化,這是快排的最壞的情況,快排此時傻眼中。。。時間復雜度為O(n*n)但是沒關系,下面第二種實現(xiàn)隨機化快排算法可以彌補這個缺憾, 它不再關心你的輸入數(shù)列是什么。

(1)基本快排算法,本示例用輸入數(shù)列的第一個值作為排序支點。

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // get the random numbers
    origin := rand.Perm(10)
    fmt.Println("origin:", origin)
    quickSort(origin, 0, len(origin))
    fmt.Println("quick sort:", origin)

}

func quickSort(list []int, start, end int) {
    if end-start > 1 {
        // get the pivot
        mid := partition(list, start, end)
        // left sort
        quickSort(list, start, mid)
        // right sort
        quickSort(list, mid+1, end)
    }
}

func partition(list []int, begin, end int) (i int) {
    cValue := list[begin]
    i = begin
    for j := i + 1; j < end; j++ {
        if list[j] < cValue {
            i++ // 這里一定要先加1后在交換值,因為支點現(xiàn)在不必交換,現(xiàn)在i 和 j(小于支點和大于支點)正在劃分邊界
            list[j], list[i] = list[i], list[j]
            fmt.Println("list:", list)
        }
    }
/* 到此,i和j的邊界已經(jīng)劃分完成,把i對應的值和支點對應的值交換后,就符合了快分的要求:i左邊對應的值都小于等于且右邊的都大于支點對應的值
此時i的值就是新的支點, 對應的值就是新的主元
*/
    list[i], list[begin] = list[begin], list[i]
    return i
}

結果:

root@slave2:~# go run quickSort.go 
origin: [9 4 2 6 8 0 3 1 7 5]
quick sort: [0 1 2 3 4 5 6 7 8 9]

(2)隨機快速排序算法
這個需要讓每次的主元(就是那個被比較值)隨機。實現(xiàn)如下:

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    //origin := rand.Perm(20) //偽隨機數(shù)
    origin := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    fmt.Println("origin:", origin)
    randomQuickSort(origin, 0, len(origin))
    fmt.Println("quick sort:", origin)

}

func randomQuickSort(list []int, start, end int) {
    if end-start > 1 {
        // get the pivot
        mid := randomPartition(list, start, end)
        randomQuickSort(list, start, mid)
        randomQuickSort(list, mid+1, end)
    }
}

func randomPartition(list []int, begin, end int) int {
    // 生成真隨機數(shù)
    i := randInt(begin, end)
    fmt.Println("random number:", i)
    // 下面這行是核心部分,隨機選擇主元, 如果沒有此次交換,就是普通快排
    list[i], list[begin] = list[begin], list[i]
    return partition(list, begin, end)
}

func partition(list []int, begin, end int) (i int) {
    cValue := list[begin]
    i = begin
    for j := i + 1; j < end; j++ {
        if list[j] < cValue {
            i++
            list[j], list[i] = list[i], list[j]
        }
    }
    list[i], list[begin] = list[begin], list[i]
    return i
}

// 真隨機數(shù)
func randInt(min, max int) int {
    rand.Seed(time.Now().UnixNano())
    return min + rand.Intn(max-min)
}
    

為了顯示隨機快排對有序數(shù)列的處理要優(yōu)于普通快排,特意輸入了0-10的有序數(shù)列,測試結果如下:
普通快排:

root@slave2:~# go run quickSort.go 
origin: [1 2 3 4 5 6 7 8 9]
random number: 6
random number: 8
random number: 2
random number: 7
random number: 5
random number: 7
random number: 6
random number: 7
quick sort: [1 2 3 4 5 6 7 8 9]

隨機快排:

root@slave2:~# go run randomQuickSort.go 
origin: [1 2 3 4 5 6 7 8 9]
random number: 7
random number: 6
random number: 4
random number: 1
random number: 2
quick sort: [1 2 3 4 5 6 7 8 9]

參考鏈接:
快排及隨機化算法
數(shù)學之美番外篇:快排為什么那樣快

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 1 初級排序算法 排序算法關注的主要是重新排列數(shù)組元素,其中每個元素都有一個主鍵。排序算法是將所有元素主鍵按某種方...
    深度沉迷學習閱讀 1,592評論 0 1
  • 排序算法基礎 排序算法,是一種能將一串數(shù)據(jù)按照特定的排序方式進行排列的一種算法,一個排序算法的好壞,主要從時間復雜...
    jackyshan閱讀 4,296評論 3 11
  • 版本記錄 前言 將數(shù)據(jù)結構和算法比作計算機的基石毫不為過,追求程序的高效是每一個軟件工程師的夢想。下面就是我對算法...
    刀客傳奇閱讀 5,384評論 4 72
  • 記得前段時間有人說過,“今天的努力工作,是為了當年吹過的牛逼”。其實這就是對堅持最好的驗證,如果一個能夠...
    功不唐捐2019閱讀 282評論 0 3
  • 風輕煙塵聾 夜來雪寒燈 樓高人心遠 苦志不言情
    劍雨黑石閱讀 174評論 0 0

友情鏈接更多精彩內容