快速排序


實現原理

快速排序思想:如果要排數組p到r之間的一組數據,選擇p到r之間任意一個一個數據作為pivot(分區點,這里選擇的是s[r]作為pivot)。遍歷p到r之間的數據,將小於pivot的數據放在左邊,其他的放右邊。經過這一步驟后數據p到r被分成了三份,前面p~q-1的數據小於pivot,q+1~r的數據大於pivot。接着遞歸分治實現剩下子分區的排序。

如下圖所示是一次分區的結果,以數組的最后一個節點4作為pivot:

 

 

代碼實現(golang)

 1 package main
 2 
 3 import "fmt"
 4 
 5 func quicklySort(s []int) []int {
 6     quickylySortImpl(s, 0, len(s)-1)
 7     return s
 8 }
 9 
10 func quickylySortImpl(s []int, p, r int) {
11     if p >= r {
12         return
13     }
14     q := partition(s, p, r)
15     quickylySortImpl(s, p, q-1)
16     quickylySortImpl(s, q+1, r)
17 }
18 
19 func partition(s []int, p, r int) int {
20     pivot := s[r]
21     i := p
22     for j := p; j <= r; j++ {
23         if s[j] < pivot {
24             s[i], s[j] = s[j], s[i]
25             i = i + 1
26         }
27     }
28     s[i], s[r] = s[r], s[i]
29     return i
30 }
31 
32 func main() {
33     fmt.Println(quicklySort([]int{7, 10, 2, 3, 6, 1, 4}))
34 }

 

程序運行輸出 1,2,3,4,6,7,10

時間復雜度O(nlogn), 空間復雜度O(1)

擴展應用

O(n)時間復雜度求數組的第K大數據

 1 package main
 2 
 3 import "fmt"
 4 
 5 func findKthLargest(nums []int, k int) int {
 6     q := findKthLargestImpl(nums, 0, len(nums)-1, k)
 7     return nums[q]
 8 }
 9 
10 func findKthLargestImpl(nums []int, p, r, k int) int {
11     if p >= r {
12         return p
13     }
14     q := partition(nums, p, r)
15     fmt.Println("pq=", q)
16     if (q + 1) == k {
17         fmt.Println("q=", q)
18         return q
19     } else if (q + 1) < k {
20         q = findKthLargestImpl(nums, q+1, r, k)
21     } else {
22         q = findKthLargestImpl(nums, p, q-1, k)
23     }
24     return q
25 }
26 
27 func partition(s []int, p, r int) int {
28     pivot := s[r]
29     i := p
30     for j := p; j <= r; j++ {
31         if s[j] > pivot {
32             s[i], s[j] = s[j], s[i]
33             i = i + 1
34         }
35     }
36     s[i], s[r] = s[r], s[i]
37     return i
38 }
39 func main() {
40     fmt.Println(findKthLargest([]int{3, 2, 1, 5, 6, 4}, 2))
41 }

程序運行輸出 5

需要特別注意的是程序32行由大於號變成了小於號,即把比pivot大的數據放左邊,讓數據從大到小,從而符合第K大的判斷要求。如果求第K小則不用動。

第一遍運行數組的排序是 5, 6,4,3,2,1  q = 2即元素4,進入了代碼第24行的邏輯 findKthLargestImpl(nums, 0, 1, 2)

第二遍運行數組的排序是 6,5,4,3,2,1  q = 0即元素6,進入了代碼第20行的邏輯 findKthLargestImpl(nums, 1, 1, 2)

第三遍運行直接返回1,即元素5

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM