golang實現四種排序(快速,冒泡,插入,選擇)


本文系轉載

原文地址:

http://www.limerence2017.com/2019/06/29/golang07/

前面已經介紹golang基本的語法和容器了,這一篇文章用golang實現四種排序算法,快速排序,插入排序,選擇排序,冒泡排序。既可以總結前文的基礎知識,又可以熟悉下golang如何實現這四種排序。

快速排序

算法介紹

假設用戶輸入了如下數組

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 6 | 2 | 7 | 3 | 8 | 9 |

創建變量i=0(指向第一個數據), j=5(指向最后一個數據), k=6(賦值為第一個數據的值)
我們要把所有比k小的數移動到k的左面,所以我們可以開始尋找比6小的數,從j開始,從右往左找,不斷遞減變量j的值,我們找到第一個下標3的數據比6小,於是把數據3移到下標0的位置,把下標0的數據6移到下標3,完成第一次比較

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 3 | 2 | 7 | 6 | 8 | 9 |

i=0 j=3 k=6
接着,開始第二次比較,這次要變成找比k大的了,而且要從前往后找了。遞加變量i,發現下標2的數據是第一個比k大的,於是用下標2的數據7和j指向的下標3的數據的6做交換,數據狀態變成下表:

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 3 | 2 | 6 | 7 | 8 | 9 |

i=2,j=3,k=6
接下來繼續重復上邊的步驟,從j開始,從右往左找比k小的,此時i=2,j=3,j再移動一位就和i相等了,此時就完成了k=6的排序,此時k=6,i和j相等都為2,6右邊的數都比6大,6左邊的數比6小。
接下來分別比較6左邊的序列(下標從0到1)和6右邊(下標從3到5)的序列,同樣采用上述辦法,直到所有序列都比較完成。

算法實現

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
func quickSort(slice []int, begin int, end int) {
//slice為空
if len(slice) == 0 {
return
}
//end越界
if end >= len(slice) {
return
}
//begin越界
if begin < 0 {
return
}
//下標碰頭無須比較
if begin >= end {
return
}
//i從左到右,j從右到左
i := begin
j := end
//value就是比較的值
value := slice[i]

for {
//從右往左比較,找到比value小的交換位置
index := j
for ; index > i; index-- {
if value > slice[index] {
slice[i] = slice[index]
//slice[index] = value
break
}
}
//更新j的位置
j = index
//從左往右比較
for index = i; index < j; index++ {
if value < slice[index] {
slice[j] = slice[index]
//slice[index] = value
break
}
}
//更新i的位置
i = index
//i和j碰頭則更新value的位置,並且比較value左右序列
//fmt.Println(i, j)
if i >= j {
slice[i] = value
quickSort(slice, begin, i-1)
quickSort(slice, i+1, end)
return
}
//否則繼續比較,此時i,j已經縮小范圍
}

}
上述算法時間復雜度達到O(nlogn)

插入排序

算法描述

假設用戶輸入了如下數組

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 6 | 2 | 7 | 3 | 8 | 9 |

假設從小到大排序
插入排序先從下標為1的元素2開始,比較前邊下標為0的元素6,2比6小,則將6移動到2的位置,2放到6的位置

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 2 | 6 | 7 | 3 | 8 | 9 |

記下來比較下標為2的元素7,和前邊0~1下標的元素對比,從后往前找,如果找到比7大的元素,則將該元素后邊的序列依次后移,將7插入該元素位置
目前7不需要移動。
接下來尋找下標為3 的元素3,從下標3往前找,由於下標1,下標2的元素都比3大,所以依次后移,將3放倒下標1的位置。

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 2 | 3 | 6 | 7 | 8 | 9 |
以此類推,進行比較。

算法實現

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func insertSort(slice []int) {
if len(slice) <= 0 {
return
}

for i := 1; i < len(slice); i++ {
//下標i的元素temp
temp := slice[i]
for j := i - 1; j >= 0; j-- {
//從i-1的位置往前查找,如果前邊的元素比temp大
//就進行后移
if temp < slice[j] {
slice[j+1] = slice[j]
}
//否則找到比temp小的就將tmep插入。
slice[j+1] = temp
break
}
}
}

該算法時間復雜度為O(n*n)

冒泡排序

算法描述

假設用戶輸入了如下數組

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 6 | 2 | 7 | 3 | 8 | 9 |
冒泡排序依次比較相鄰的兩個元素 ,將大的元素后移即可。
先比較下標為0和下標為1的元素,6比2大,所以6和2交換位置。

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 2 | 6 | 7 | 3 | 8 | 9 |
接下來比較下標為1和下標為2的元素,6比7小所以不做交換。然后比較7和3,7比3大,7和三交換位置,以此類推,直到比較到最后一個元素

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 2 | 6 | 3 | 7 | 8 | 9 |
經過這一輪相鄰元素的比較,將最大的元素9冒泡到最后的位置。
接下來重復上述步驟,從下標0開始到下標4兩兩比較,將第二大元素放到下標4的位置,因為下標5已經是最大元素,所以不參與比較。

算法實現

1
2
3
4
5
6
7
8
9
func bubbleSort(slice []int) {
for i := 0; i < len(slice); i++ {
for j := 0; j < len(slice)-i-1; j++ {
if slice[j] > slice[j+1] {
slice[i], slice[j+1] = slice[j+1], slice[j]
}
}
}
}

選擇排序

算法描述

假設用戶輸入了如下數組

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 6 | 2 | 7 | 3 | 8 | 9 |
從下標0開始,比較6和其他位置的元素,找到最小的元素2和6交換位置

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 2 | 6 | 7 | 3 | 8 | 9 |
接下來從下標1開始,比較6和后邊位置的元素,選擇最小的和6交換位置。

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 2 | 3 | 7 | 6 | 8 | 9 |
以此類推,從下標2開始,比較7和后邊的元素,選擇最小的6交換位置

下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數值 | 2 | 3 | 6 | 7 | 8 | 9 |
以此類推,直到下標5的位置元素都比較完。

算法實現

1
2
3
4
5
6
7
8
9
func selectSort(slice []int) {
for i := 0; i < len(slice); i++ {
for j := i + 1; j < len(slice); j++ {
if slice[i] > slice[j] {
slice[i], slice[j] = slice[j], slice[i]
}
}
}
}

該算法時間復雜度為o(n*n)

main函數中調用並測試

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
array := [...]int{6, 2, 7, 3, 8, 9}
slice := array[:]
quickSort(slice, 0, len(slice)-1)
fmt.Println(slice)
slice2 := array[:]
bubbleSort(slice2)
fmt.Println(slice2)
slice3 := array[:]
selectSort(slice3)
fmt.Println(slice3)
slice4 := array[:]
insertSort(slice4)
fmt.Println(slice4)

}

到此為止,四種基本的比較算法已經完成,感興趣的可以自己實現以下。
上述所有源碼下載地址
源碼下載地址
謝謝關注我的公眾號
wxgzh.jpg


免責聲明!

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



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