几种排序Go实现

直接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

一个没有高级趣味的人。 email:hushui502@gmail.com
原文地址:https://www.cnblogs.com/CherryTab/p/12825780.html