go實現十大經典排序
阿新 • • 發佈:2022-05-11
package sort import ( "math" "math/rand" "strconv" "time" ) func newNums(k int) []int { rand.Seed(time.Now().UnixNano()) ans := make([]int, k) for i:=0;i<k;i++ { ans[i] = rand.Intn(1000000) } return ans } var Nums = newNums(100000) func BubbleSort(nums []int) []int { for i:=0;i<len(nums);i++ { for j:=1;j<len(nums)-i;j++ { if nums[j-1] > nums[j] { nums[j-1], nums[j] = nums[j], nums[j-1] } } } return nums } func SelectSort(nums []int) []int { for i:=0; i<len(nums);i++ { for j:=i+1;j<len(nums);j++ { if nums[i] > nums[j] { nums[i], nums[j] = nums[j], nums[i] } } } return nums } func InsertSort(nums []int) []int { /* 插入排序 [有序區, 無序區] 每輪迴圈,將該輪迴圈的數值放入其及其前方的合適的位置 1.如果當輪該數比有序區的最後一個數大或等,繼續下輪比較 2.如果當輪該數比有序區的最後一個數小,繼續向前比較,直到找到比有序區大或等的數停止|很小時,該數放到最前 */ for i:=1;i<len(nums);i++ { tmp := nums[i] j := i-1 for j>=0 && nums[j] > tmp { nums[j+1] = nums[j] j-- } nums[j+1] = tmp } return nums } func HellSort(nums []int) []int { step := len(nums)/2 for step > 0 { for i:=step;i<len(nums);i++ { j := i for j-step >= 0 && nums[j-step] > nums[j] { nums[j-step], nums[j] = nums[j], nums[j-step] j -= step } } step /= 2 } return nums } func MergeSort(nums []int) []int { if len(nums) <= 1 {return nums} merge := func(left, right []int) []int { res := make([]int, len(left)+len(right)) var lIdx, rIdx, i int for lIdx < len(left) && rIdx < len(right) { if left[lIdx] < right[rIdx] { res[i] = left[lIdx] lIdx++ } else { res[i] = right[rIdx] rIdx++ } i++ } if lIdx < len(left)-1 { copy(res[i:], left[lIdx:]) } else { copy(res[i:], right[rIdx:]) } return res } var sort func(nums []int) []int sort = func(nums []int) []int { if len(nums) <= 1 { return nums } mid := len(nums)/2 left := sort(nums[:mid]) right := sort(nums[mid:]) return merge(left, right) } return sort(nums) } func QuickSort(nums []int) []int { var quick func(left, right int) []int quick = func(left, right int) []int { if left > right { return nil } i, j, pivot := left, right, nums[(left+right)/2] for i<j { for i<j && nums[j] >= pivot { j-- } for i<j && nums[i] <= pivot { i++ } nums[i], nums[j] = nums[j], nums[i] } nums[i], nums[(left+right)/2] = nums[(left+right)/2], nums[i] quick(left, i-1) quick(i+1, right) return nums } return quick(0, len(nums)-1) } func HeapSort(nums []int) []int { heapify := func(nums []int, root, end int) { for { child := root*2 + 1 if child > end { return } if child < end && nums[child] <= nums[child+1] { child++ } if nums[root] > nums[child] { return } nums[root], nums[child] = nums[child], nums[root] root = child } } end := len(nums)-1 // heapify for i:=end/2;i>=0;i-- { heapify(nums, i, end) } for i:=end;i>0;i-- { nums[0], nums[i] = nums[i], nums[0] end-- heapify(nums, 0, end) } return nums } func CountSort(nums []int) []int { if len(nums) <= 1 { return nums } findMinMax := func(nums []int) (int, int) { min := math.MaxInt32 max := math.MinInt32 for i:=0;i<len(nums);i++ { if nums[i] > max { max = nums[i] } if nums[i] < min { min = nums[i] } } return min, max } min, max := findMinMax(nums) tmpNums := make([]int, max-min+1) for i:=0;i<len(nums);i++ { tmpNums[nums[i]-min]++ } j := 0 for i:=0;i<len(nums);i++ { for tmpNums[j] == 0 { j++ } nums[i] = j+min tmpNums[j]-- } return nums } func RadixSort(nums []int) []int { if len(nums) <= 1 { return nums } max := nums[0] for i:=1;i<len(nums);i++ { if nums[i] > max { max = nums[i] } } for i:=0;i<len(strconv.Itoa(max));i++ { buckets := make([][]int, 10) // partition for j:=0;j<len(nums);j++ { bucket := nums[j] / int(math.Pow10(i)) % 10 buckets[bucket] = append(buckets[bucket], nums[j]) } // sort cur bucket m := 0 for k:=0;k<len(buckets);k++ { for p:=0;p<len(buckets[k]);p++ { nums[m] = buckets[k][p] m++ } } } return nums } func BucketSort(nums []int) []int { if len(nums) < 2 { return nums } min, max := nums[0], nums[0] for i:=0;i<len(nums);i++ { if nums[i] > max { max = nums[i] } if nums[i] < min { min = nums[i] } } bucketSize := 5 bucketCap := (max-min)/bucketSize + 1 buckets := make([][]int, bucketCap) for i:=0;i<bucketCap;i++ { buckets[i] = make([]int, 0) } // partition for i:=0;i<len(nums);i++ { bucketsSeq := (nums[i]-min)/bucketSize buckets[bucketsSeq] = append(buckets[bucketsSeq], nums[i]) } // 桶中排序,然後裝桶 index := 0 for _, bucket := range buckets { bucket := func(arr []int) []int { for i:=0;i<len(arr);i++ { tmp := arr[i] j := i-1 for j>=0 && arr[j] > tmp { arr[j+1] = arr[j] j-- } arr[j+1] = tmp } return arr }(bucket) for _, num := range bucket { nums[index] = num index++ } } return nums }