Golang(二十四)[排序算法-計數排序]

在這裏插入圖片描述
計數排序/計數統計排序/變相插入排序

1.簡介

計數排序(Counting sort) 是一種穩定的線性時間排序算法.計數排序的核心在於將輸入的數據值轉化爲鍵存儲在額外開闢的數組空間中。作爲一種線性時間複雜度的排序,計數排序要求輸入的數據必須是有確定範圍的整數。計數排序使用一個額外的數組C,其中第i個元素是待排序數組A中值等於i的元素的個數。然後根據數組C 來將A中的元素排到正確的位置。

2.原理

  • 找出待排序的數組中最大和最小的元素.
  • 統計數組中每個值爲i的元素出現的次數,存入數組C的第i項.
  • 對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加).
  • 反向填充目標數組:將每個元素 i放在新數組的第C[i]項,每放一個元素就將C[i]減去1.

3.操作規則

4.Golang代碼

1.升序

// 計數排序--升序
func ContingSortAsc(slice []int) {
	// 創建map統計0-999每個數出現的次數
	m := make(map[int]int)
	// 遍歷待排序的數據,統計結果
	for _, v := range slice {
		m[v]++
	}
	// 藉助map,統計排序的數據重新賦值爲原序列
	slice = slice[0:0] // 將原序列清空
	for i := 0; i < 1000; i++ {
		// for i := 0; i < 1000; i++ {
		// 數據出現的次數:m[i]的值
		for j := 0; j < m[i]; j++ {
			slice = append(slice, i) // 重新賦值
		}
	}
}

2.降序

// 計數排序--降序
func ContingSortDesc(slice []int) {
	// 創建map統計0-999每個數出現的次數
	m := make(map[int]int)
	// 遍歷待排序的數據,統計結果
	for _, v := range slice {
		m[v]++
	}
	// 藉助map,統計排序的數據重新賦值爲原序列
	slice = slice[0:0] // 將原序列清空
	for i := 999; i >= 0; i-- {
		// for i := 0; i < 1000; i++ {
		// 數據出現的次數:m[i]的值
		for j := 0; j < m[i]; j++ {
			slice = append(slice, i) // 重新賦值
		}
	}
}

3.測試

func main() {
	slice := make([]int, 0)
	// 設置隨機數種子
	rand.Seed(time.Now().UnixNano())
	// 生成100個1000以內的隨機數
	for i := 1; i <= 100; i++ {
		slice = append(slice, rand.Intn(1000))
	}
	fmt.Println("原數據:", slice)
	ContingSortAsc(slice)
	fmt.Println("計數排序升序:", slice)
	ContingSortDesc(slice)
	fmt.Println("計數排序降序:", slice)
}

5.完整代碼

package main

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

// 計數排序--升序
func ContingSortAsc(slice []int) {
	// 創建map統計0-999每個數出現的次數
	m := make(map[int]int)
	// 遍歷待排序的數據,統計結果
	for _, v := range slice {
		m[v]++
	}
	// 藉助map,統計排序的數據重新賦值爲原序列
	slice = slice[0:0] // 將原序列清空
	for i := 0; i < 1000; i++ {
		// for i := 0; i < 1000; i++ {
		// 數據出現的次數:m[i]的值
		for j := 0; j < m[i]; j++ {
			slice = append(slice, i) // 重新賦值
		}
	}
}

// 計數排序--降序
func ContingSortDesc(slice []int) {
	// 創建map統計0-999每個數出現的次數
	m := make(map[int]int)
	// 遍歷待排序的數據,統計結果
	for _, v := range slice {
		m[v]++
	}
	// 藉助map,統計排序的數據重新賦值爲原序列
	slice = slice[0:0] // 將原序列清空
	for i := 999; i >= 0; i-- {
		// for i := 0; i < 1000; i++ {
		// 數據出現的次數:m[i]的值
		for j := 0; j < m[i]; j++ {
			slice = append(slice, i) // 重新賦值
		}
	}
}

func main() {
	slice := make([]int, 0)
	// 設置隨機數種子
	rand.Seed(time.Now().UnixNano())
	// 生成100個1000以內的隨機數
	for i := 1; i <= 100; i++ {
		slice = append(slice, rand.Intn(1000))
	}
	fmt.Println("原數據:", slice)
	ContingSortAsc(slice)
	fmt.Println("計數排序升序:", slice)
	ContingSortDesc(slice)
	fmt.Println("計數排序降序:", slice)
}

原數據: [657 58 694 781 52 352 755 659 335 929 815 957 919 537 861 70 249 746 88 485 456 414 13 378 911 173 252 182 716 248 15 581 508 469 112 83 427 950 995 4 420
256 134 405 746 246 584 174 203 923 742 76 627 643 405 285 262 363 657 673 629 247 891 668 478 253 131 6 215 72 36 785 546 614 586 187 157 394 867 579 786 697 773 116 397 642 186 900 850 624 982 580 890 952 816 748 595 33 978 946]
計數排序升序: [4 6 13 15 33 36 52 58 70 72 76 83 88 112 116 131 134 157 173 174 182 186 187 203 215 246 247 248 249 252 253 256 262 285 335 352 363 378 394 397 405
405 414 420 427 456 469 478 485 508 537 546 579 580 581 584 586 595 614 624 627 629 642 643 657 657 659 668 673 694 697 716 742 746 746 748 755 773 781 785 786 815 816 850 861 867 890 891 900 911 919 923 929 946 950 952 957 978 982 995]
計數排序降序: [995 982 978 957 952 950 946 929 923 919 911 900 891 890 867 861 850 816 815 786 785 781 773 755 748 746 746 742 716 697 694 673 668 659 657 657 643 642 629 627 624 614 595 586 584 581 580 579 546 537 508 485 478 469 456 427 420 414 405 405 397 394 378 363 352 335 285 262 256 253 252 249 248 247 246 215 203 187 186 182 174 173 157 134 131 116 112 88 83 76 72 70 58 52 36 33 15 13 6 4]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章