直接po代码了,网上一堆图解,可以先看看图解再理解代码。
package main import "fmt" func bubbleSort(array []int) []int { swapped := true for swapped { swapped = false for i := 0; i < len(array)-1; i++ { if array[i + 1] < array[i] { array[i + 1], array[i] = array[i], array[i + 1] swapped = true } } } return array } func main() { a := []int{2, 1, 5, 3} b := bubbleSort(a) fmt.Println(b) }
package main type MaxHeap struct { slice []int heapSize int } func BuildMaxHeap(slice []int) MaxHeap { h := MaxHeap{slice:slice, heapSize:len(slice)} for i := len(slice) / 2; i >= 0; i-- { h.MaxHeapify(i) } return h } func (h MaxHeap) MaxHeapify(i int) { l, r := 2*i+1, 2*i+2 max := i if l < h.size() && h.slice[l] > h.slice[max] { max = l } if r < h.size() && h.slice[r] > h.slice[max] { max = r } if max != i { h.slice[i], h.slice[max] = h.slice[max], h.slice[i] h.MaxHeapify(max) } } func (h MaxHeap) size() int { return h.heapSize } func heapSort(arr []int) []int { h := BuildMaxHeap(arr) for i := len(h.slice) - 1; i >= 1; i-- { h.slice[0], h.slice[i] = h.slice[i], h.slice[0] h.heapSize -= 1 h.MaxHeapify(0) } return h.slice }
package main func insertionSort(arr []int) []int { for out := 1; out < len(arr); out++ { temp := arr[out] in := out for ; in > 0 && arr[in-1] >= temp; in-- { arr[in] = arr[in-1] } arr[in] = temp } return arr }
package main func merge(a, b []int) []int { r := make([]int, len(a)+len(b)) i := 0 j := 0 for i < len(a) && j < len(b) { if a[i] <= b[j] { r[i+j] = a[i] i++ } else { r[i+j] = b[j] j++ } } for i < len(a) { r[i+j] = a[i] i++ } for j < len(b) { r[i+j] = b[j] j++ } return r } func MergeSort(items []int) []int { if len(items) < 2 { return items } middle := len(items) / 2 a := MergeSort(items[:middle]) b := MergeSort(items[middle:]) return merge(a, b) }
package main import "math/rand" func quickSort(arr []int) []int { if len(arr) <= 1 { return arr } median := arr[rand.Intn(len(arr))] low_part := make([]int, 0, len(arr)) middle_part := make([]int, 0, len(arr)) high_part := make([]int, 0, len(arr)) for _, item := range arr { switch { case item < median: low_part = append(low_part, item) case item > median: high_part = append(high_part, item) case item == median: middle_part = append(middle_part, item) } } low_part = quickSort(low_part) high_part = quickSort(high_part) low_part = append(low_part, middle_part...) high_part = append(low_part, high_part...) return low_part }
package main func selectionSort(arr []int) []int { for i := 0; i < len(arr); i++ { min := i for j := i + 1; j < len(arr); j++ { if arr[min] > arr[j] { min = j } } tmp := arr[i] arr[i] = arr[min] arr[min] = tmp } return arr }
package main func shellSort(arr []int) []int { for d := int(len(arr) / 2); d > 0; d /= 2 { for i := d; i < len(arr); i++ { for j := i; j >= d && arr[j-d] > arr[j]; j -= d { arr[j], arr[j-d] = arr[j-d], arr[j] } } } return arr }
test
package sorts import "testing" //BEGIN TESTS func TestBubble(t *testing.T) { for _, test := range sortTests { actual := bubbleSort(test.input) pos, sorted := compareSlices(actual, test.expected) if !sorted { if pos == -1 { t.Errorf("test %s failed due to slice length changing", test.name) } t.Errorf("test %s failed at index %d", test.name, pos) } } } func TestSelection(t *testing.T) { for _, test := range sortTests { actual := selectionSort(test.input) pos, sorted := compareSlices(actual, test.expected) if !sorted { if pos == -1 { t.Errorf("test %s failed due to slice length changing", test.name) } t.Errorf("test %s failed at index %d", test.name, pos) } } } func TestInsertion(t *testing.T) { for _, test := range sortTests { actual := insertionSort(test.input) pos, sorted := compareSlices(actual, test.expected) if !sorted { if pos == -1 { t.Errorf("test %s failed due to slice length changing", test.name) } t.Errorf("test %s failed at index %d", test.name, pos) } } } func TestMerge(t *testing.T) { for _, test := range sortTests { actual := Mergesort(test.input) pos, sorted := compareSlices(actual, test.expected) if !sorted { if pos == -1 { t.Errorf("test %s failed due to slice length changing", test.name) } t.Errorf("test %s failed at index %d", test.name, pos) } } } func TestHeap(t *testing.T) { for _, test := range sortTests { actual := heapSort(test.input) pos, sorted := compareSlices(actual, test.expected) if !sorted { if pos == -1 { t.Errorf("test %s failed due to slice length changing", test.name) } t.Errorf("test %s failed at index %d", test.name, pos) } } } func TestQuick(t *testing.T) { for _, test := range sortTests { actual := quickSort(test.input) pos, sorted := compareSlices(actual, test.expected) if !sorted { if pos == -1 { t.Errorf("test %s failed due to slice length changing", test.name) } t.Errorf("test %s failed at index %d", test.name, pos) } } } func TestShell(t *testing.T) { for _, test := range sortTests { actual := shellSort(test.input) pos, sorted := compareSlices(actual, test.expected) if !sorted { if pos == -1 { t.Errorf("test %s failed due to slice length changing", test.name) } t.Errorf("test %s failed at index %d", test.name, pos) } } } /*func TestTopological(t *testing.T) { for _, test := range sortTests { actual := topologicalSort(test.input) pos, sorted := compareSlices(actual, test.expected) if !sorted { if pos == -1 { t.Errorf("test %s failed due to slice length changing", test.name) } t.Errorf("test %s failed at index %d", test.name, pos) } } }*/ //END TESTS //BEGIN BENCHMARKS func BenchmarkBubble(b *testing.B) { for i := 0; i < b.N; i++ { for _, test := range sortTests { bubbleSort(test.input) } } } func BenchmarkSelection(b *testing.B) { for i := 0; i < b.N; i++ { for _, test := range sortTests { selectionSort(test.input) } } } func BenchmarkInsertion(b *testing.B) { for i := 0; i < b.N; i++ { for _, test := range sortTests { insertionSort(test.input) } } } func BenchmarkMerge(b *testing.B) { for i := 0; i < b.N; i++ { for _, test := range sortTests { Mergesort(test.input) } } } func BenchmarkHeap(b *testing.B) { for i := 0; i < b.N; i++ { for _, test := range sortTests { heapSort(test.input) } } } func BenchmarkQuick(b *testing.B) { for i := 0; i < b.N; i++ { for _, test := range sortTests { quickSort(test.input) } } } func BenchmarkShell(b *testing.B) { for i := 0; i < b.N; i++ { for _, test := range sortTests { shellSort(test.input) } } } /*func BenchmarkTopological(b *testing.B) { for i := 0; i < b.N; i++ { for _, test := range sortTests { topologicalSort(test.input) } } }*/ //END BENCHMARKS func compareSlices(a []int, b []int) (int, bool) { if len(a) != len(b) { return -1, false } for pos := range a { if a[pos] != b[pos] { return pos, false } } return -1, true }
end