Counting Sort 是一種非比較型整數排序演演算法,適用於一定範圍內的整數排序。它的基本思想是,對每一個輸入元素 x,確定小於 x 的元素個數,從而確定 x 在輸出陣列中的位置。
下面是使用 Go 語言實現的 Counting Sort 演演算法的程式碼:
package main
import (
"fmt"
)
func countingSort(array []int) []int {
// 找出陣列中的最大值和最小值
max := int(^uint(0) >> 1)
min := int(^uint(max) >> 1)
// 初始化計數陣列,長度為最大值減最小值加1
count := make([]int, max-min+1)
// 統計每個元素出現的次數
for _, v := range array {
count[v-min]++
}
// 重新賦值,使得每個元素等於它出現的次數加上之前已經排序好的元素個數
index := 0
for i, v := range count {
for v > 0 {
array[index] = i + min
count[i]--
index++
}
}
return array
}
func main() {
array := []int{6, 0, 2, 0, 1, 3, 4, 6, 1, 3, 2}
fmt.Println(countingSort(array))
}
這段程式碼首先找到輸入陣列的最大值和最小值,然後建立一個計數陣列,長度為最大值減去最小值再加1。然後遍歷輸入陣列,對每個元素在計數陣列中對應的位置增加1。最後,重新賦值,使得每個元素等於它出現的次數加上之前已經排序好的元素個數。這樣就可以得到排序後的陣列。
首先,我們需要了解COUNTING-SORT演演算法的基本原理。COUNTING-SORT是一種線性時間複雜度的排序演演算法,它的基本思想是對陣列中的每個元素進行計數,然後根據計數結果對元素進行排序。具體操作過程如下:
1.初始化一個計數陣列count,用於儲存每個元素出現的次數。
2.遍歷陣列A,對每個元素進行計數。
3.根據計數陣列count,將元素重新放回陣列A中的正確位置。
下面是使用Go語言實現的COUNTING-SORT演演算法,並對陣列A=(6,0,2,0,1,3,4,6,1,3,2)進行排序的過程:
package main
import (
"fmt"
)
func countingSort(arr []int) {
count := make([]int, len(arr)+1)
for i := 0; i < len(arr); i++ {
count[arr[i]]++
}
for i := 1; i < len(count); i++ {
count[i] += count[i-1]
}
result := make([]int, len(arr))
for i := len(arr) - 1; i >= 0; i-- {
result[count[arr[i]]-1] = arr[i]
count[arr[i]]--
}
copy(arr, result)
}
func main() {
arr := []int{6, 0, 2, 0, 1, 3, 4, 6, 1, 3, 2}
fmt.Println("原始陣列:", arr)
countingSort(arr)
fmt.Println("排序後的陣列:", arr)
}
執行上述程式碼,可以得到陣列A在COUNTING-SORT演演算法下的排序結果:
原始陣列: [6 0 2 0 1 3 4 6 1 3 2]
排序後的陣列: [0 0 1 1 2 2 3 3 3 4 6 6]
首先,我們需要確定陣列 A 中有多少元素。使用 range 迴圈遍歷陣列 A,並使用變數 count 記錄當前元素的位置。
for i := 0; i < len(A); i++ {
count := i
// ...
}
接下來,我們可以使用一個 for 迴圈將每個元素從 count 的位置開始逐個比較,直到達到 count + 1 的位置為止。在每次比較中,如果當前元素大於下一個元素,就將它們交換位置。
for i, count := range A {
if A[i] > A[count]:
A[i], A[count] = A[count], A[i]
count++
}
最後,我們可以使用 range 迴圈遍歷陣列 A,並使用變數 sum 記錄每個元素的累加和。然後,我們可以將結果輸出到控制檯。
for i, count := range A {
sum += A[i]
fmt.Printf("Element %d: %d
", i+1, A[i])
}
完整程式碼如下:
package main
import "fmt"
func main() {
A := []int{6, 0, 2, 0, 1, 3, 4, 6, 1, 3, 2}
for i, count := range A {
sum += A[i]
fmt.Printf("Element %d: %d
", i+1, A[i])
}
fmt.Println()
}
COUNTING-SORT 是一種對陣列進行排序的演演算法,其基本思想是統計陣列中每個元素的出現次數,然後將計數結果儲存在一個新的陣列中,接著將新陣列中的元素還原到原陣列中,從而實現對原陣列的排序。
以下是使用 Go 語言實現 COUNTING-SORT 演演算法對陣列 A=(6,0,2,0,1,3,4,6,1,3,2) 進行排序的過程:
1.初始化一個長度為 10 的陣列 count,用於儲存每個元素的出現次數。
2.遍歷陣列 A 中的元素,將 count 陣列中對應元素的計數加 1。
3.建立一個長度為 10 的臨時陣列 temp,用於儲存排序後的元素。
4.遍歷 count 陣列,將 count 陣列中每個元素的值還原到 temp 陣列中,同時將 temp 陣列的對應位置置為 1。
5.將 temp 陣列的元素複製回陣列 A。
下面是使用 Go 語言實現上述過程的程式碼:
package main
import "fmt"
func countingSort(A []int) []int {
count := make([]int, 10) // 初始化計數陣列
for _, v := range A {
count[v]++ // 統計每個元素的出現次數
}
temp := make([]int, len(A)) // 初始化臨時陣列
for _, v := range count {
for v == 0 {
temp[v] = 0 // 將計數為 0 的元素值還原到臨時陣列中
v++
}
}
for i := 0; i < len(A); i++ {
A[i] = temp[i] // 將臨時陣列的元素複製回原陣列
}
return A
}
func main() {
A := []int{6, 0, 2, 0, 1, 3, 4, 6, 1, 3, 2}
fmt.Println("Before sorting:", A)
fmt.Println("After sorting:", countingSort(A))
}
執行上述程式碼,可以得到排序後的陣列 A:[0 0 1 1 2 2 3 3 4 6 6]。
COUNTING-SORT 是一種基於計數排序的排序演演算法,其基本思路是先統計待排序序列中每個元素出現的次數,然後根據元素出現的次數從小到大依次輸出元素。
在對陣列 A=(6,0,2,0,1,3,4,6,1,3,2) 進行 COUNTING-SORT 操作的過程如下:
1.初始化計數陣列 C,其中 C[i] 表示元素 i 在原始陣列 A 中出現的次數。初始狀態下,C[i] 均為 0。
2.遍歷原始陣列 A,將每個元素 A[i] 的出現次數累加到計數陣列 C 中,即 C[A[i]]++。
3.找到最大的元素 M,即 M=max(A...)。
4.建立一個新的陣列 B,其長度為 M+1。
5.遍歷計數陣列 C,將每個元素 A[i] 在陣列 B 中對應的位置的值設為 C[A[i]]。即 B[C[A[i]]] = A[i]。
6.從陣列 B 的第一位開始,輸出每個元素,直到輸出到最後一位。
在對陣列 A=(6,0,2,0,1,3,4,6,1,3,2) 進行 COUNTING-SORT 操作的過程中,每個元素的出現次數如下:
6: 2
0: 2
2: 2
1: 2
3: 2
4: 1
6: 1
1: 1
3: 1
2: 1
根據元素出現的次數從小到大依次輸出元素,得到的有序陣列為:
1, 1, 2, 2, 2, 3, 3, 4, 6, 6
下面是使用 Go 語言實現 COUNTING-SORT 演演算法的範例程式碼,參照圖8-2的方法對陣列 A=(6,0,2,0,1,3,4,6,1,3,2) 進行排序:
package main
import "fmt"
// 匯入 fmt 包
func countingSort(arr []int) []int {
// 初始化計數陣列
count := make([]int, 10)
for i := 0; i < 10; i++ {
count[i] = 0
}
// 統計每個元素出現的次數
for _, num := range arr {
count[num]++
}
// 計算每個元素在排好序陣列中的位置
index := make([]int, len(arr))
for i := 0; i < len(arr); i++ {
index[count[arr[i]]-1] = arr[i]
count[arr[i]]--
}
// 將排好序的陣列複製回原陣列
copy(arr, index)
return arr
}
func main() {
// 定義測試陣列
arr := []int{6, 0, 2, 0, 1, 3, 4, 6, 1, 3, 2}
// 輸出原始陣列
fmt.Println("Original array:", arr)
// 對陣列進行 COUNTING-SORT 排序
arr = countingSort(arr)
// 輸出排序後的陣列
fmt.Println("Sorted array:", arr)
}
執行上述程式碼,輸出結果為:
Original array: [6 0 2 0 1 3 4 6 1 3 2]
Sorted array: [0 0 1 1 2 2 3 4 6 6 6]
可以看到,COUNTING-SORT 演演算法成功地對陣列 A 進行了排序,並得到了正確的結果。
COUNTING-SORT 是一種線性時間複雜度的排序演演算法,適用於待排序元素的範圍比較有限的情況。下面是參照圖8-2的方法在陣列 A=(6, 0, 2, 0, 1, 3, 4, 6, 1, 3, 2) 上執行 COUNTING-SORT 的操作過程:
1.初始化計數陣列 C:
C = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
陣列 C 的長度為待排序陣列 A 的最大值加1,即10。
2.計算每個元素出現的次數:
遍歷陣列 A,統計每個元素出現的次數,並在陣列 C 對應的位置上增加計數。
A[0] = 6,C[6] = C[6] + 1 = 1
A[1] = 0,C[0] = C[0] + 1 = 1
A[2] = 2,C[2] = C[2] + 1 = 1
A[3] = 0,C[0] = C[0] + 1 = 2
A[4] = 1,C[1] = C[1] + 1 = 1
A[5] = 3,C[3] = C[3] + 1 = 1
A[6] = 4,C[4] = C[4] + 1 = 1
A[7] = 6,C[6] = C[6] + 1 = 2
A[8] = 1,C[1] = C[1] + 1 = 2
A[9] = 3,C[3] = C[3] + 1 = 2
A[10] = 2,C[2] = C[2] + 1 = 2
統計完成後,陣列 C 的內容為:C = [2, 2, 2, 2, 1, 0, 2, 0, 0, 0]
3.累加計數陣列 C:
對陣列 C 進行累加, C[i] = C[i] + C[i-1]。
C = [2, 4, 6, 8, 9, 9, 11, 11, 11, 11]
4.構建有序輸出陣列 B:
初始化輸出陣列 B,長度與待排序陣列 A 相同。
B = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
從右向左遍歷陣列 A,根據計數陣列 C 的值,將元素放置到有序陣列 B 的相應位置上,同時更新計數陣列 C 的值。
A[10] = 2,C[2] = C[2] - 1 = 1,B[1] = 2
A[9] = 3,C[3] = C[3] - 1 = 1,B[2] = 3
A[8] = 1,C[1] = C[1] - 1 = 1,B[3] = 1
A[7] = 6,C[6] = C[6] - 1 = 1,B[4] = 6
A[6] = 4,C[4] = C[4] - 1 = 0,B[5] = 4
A[5] = 3,C[3] = C[3] - 1 = 0,B[6] = 3
A[4] = 1,C[1] = C[1] - 1 = 0,B[7] = 1
A[3] = 0,C[0] = C[0] - 1 = 1,B[8] = 0
A[2] = 2,C[2] = C[2] - 1 = 0,B[9] = 2
A[1] = 0,C[0] = C[0] - 1 = 0,B[10] = 0
A[0] = 6,C[6] = C[6] - 1 = 0,B[11] = 6
完成後,輸出陣列 B 的內容為:B = [0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 4, 6]
經過 COUNTING-SORT 操作後,陣列 A=(6, 0, 2, 0, 1, 3, 4, 6, 1, 3, 2) 被排序為 B = [0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 4, 6]。