Go之十大经典排序算法

1.冒泡排序

func bubble_sort(li []int) {
    for i := 0; i < len(li)-1; i++ {
        exchange := false
        for j := 0; j < len(li)-i-1; j++ {
            if li[j] > li[j+1] {
                li[j], li[j+1] = li[j+1], li[j]
                exchange = true
            }
        }
        if !exchange {
            return
        }
    }
}

 

2.选择排序

func select_sort(li []int) {
    for i := 0; i < len(li)-1; i++ {
        pos := i
        for j := i + 1; j < len(li); j++ {
            if li[pos] > li[j] {
                pos = j
            }
        }
        li[i], li[pos] = li[pos], li[i]
    }
}

 

3.插入排序

func insert_sort(li []int) {
    for i := 1; i < len(li); i++ {
        tmp := li[i]
        j := i - 1
        for j >= 0 && tmp < li[j] {
            li[j+1] = li[j]
            j --
        }
        li[j+1] = tmp
    }
}

 

4.希尔排序

func shell_sort(li []int) {
    for gap := len(li) / 2; gap > 0; gap /= 2 {
        for i := gap; i < len(li); i++ {
            tmp := li[i]
            j := i - gap
            for j >= 0 && tmp < li[j] {
                li[j+gap] = li[j]
                j -= gap
            }
            li[j+gap] = tmp
        }
    }
}

 

5.快速排序

func quick_sort(li []int, left, right int) {
    if left >= right {
        return
    }
    i := left
    j := right
    rand.Seed(time.Now().Unix())
    r := rand.Intn(right-left) + left
    li[i], li[r] = li[r], li[i]
    tmp := li[i]
    for i < j {
        for i < j && li[j] >= tmp {
            j--
        }
        li[i] = li[j]
        for i < j && li[i] <= tmp {
            i++
        }
        li[j] = li[i]
    }
    li[i] = tmp
    quick_sort(li, left, i-1)
    quick_sort(li, i+1, right)
}

 

6.堆排序

func sift(li []int, low, high int) {
    i := low
    j := 2*i + 1
    tmp:=li[i]
    for j <= high {
        if j < high && li[j] < li[j+1] {
            j++
        }
        if tmp < li[j] {
            li[i]  = li[j]
            i = j
            j = 2*i + 1
        } else {
            break
        }
    }
    li[i] = tmp
}

func heap_sort(li []int) {
    for i := len(li)/2 - 1; i >= 0; i-- {
        sift(li, i, len(li)-1)
    }
    for j := len(li) - 1; j > 0; j-- {
        li[0], li[j] = li[j], li[0]
        sift(li, 0, j-1)
    }
}

 

7.归并排序

func merge(li []int, left, mid, right int) {
    i := left
    j := mid + 1
    tmp := []int{}
    for i <= mid && j <= right {
        if li[i] <= li[j] {
            tmp = append(tmp, li[i])
            i ++
        } else {
            tmp = append(tmp, li[j])
            j ++
        }
    }
    if i <= mid {
        tmp = append(tmp, li[i:mid+1]...)
    } else {
        tmp = append(tmp, li[j:right+1]...)
    }
    for k := 0; k < len(tmp); k++ {
        li[left+k] = tmp[k]
    }
}

func merge_sort(li []int, left, right int) {
    if left < right {
        mid := (left + right) / 2
        merge_sort(li, left, mid)
        merge_sort(li, mid+1, right)
        merge(li, left, mid, right)
    }
}

 

8.计数排序

func count_sort(li []int) {
    max_num := li[0]
    for i := 1; i < len(li); i++ {
        if max_num < li[i] {
            max_num = li[i]
        }
    }
    arr := make([]int, max_num+1)
    for j := 0; j < len(li); j++ {
        arr[li[j]]++
    }
    k := 0
    for m, n := range arr {
        for p := 0; p < n; p++ {
            li[k] = m
            k++
        }
    }
}

 

9.桶排序

func bin_sort(li []int, bin_num int) {
    min_num, max_num := li[0], li[0]
    for i := 0; i < len(li); i++ {
        if min_num > li[i] {
            min_num = li[i]
        }
        if max_num < li[i] {
            max_num = li[i]
        }
    }
    bin := make([][]int, bin_num)
    for j := 0; j < len(li); j++ {
        n := (li[j] - min_num) / ((max_num - min_num + 1) / bin_num)
        bin[n] = append(bin[n], li[j])
        k := len(bin[n]) - 2
        for k >= 0 && li[j] < bin[n][k] {
            bin[n][k+1] = bin[n][k]
            k--
        }
        bin[n][k+1] = li[j]
    }
    o := 0
    for p, q := range bin {
        for t := 0; t < len(q); t++ {
            li[o] = bin[p][t]
            o++
        }
    }
}

 

10.基数排序

func radix_sort(li []int) {
    max_num := li[0]
    for i := 0; i < len(li); i++ {
        if max_num < li[i] {
            max_num = li[i]
        }
    }
    for j := 0; j < len(strconv.Itoa(max_num)); j++ {
        bin := make([][]int, 10)
        for k := 0; k < len(li); k++ {
            n := li[k] / int(math.Pow(10, float64(j))) % 10
            bin[n] = append(bin[n], li[k])
        }
        m := 0
        for p := 0; p < len(bin); p++ {
            for q := 0; q < len(bin[p]); q++ {
                li[m] = bin[p][q]
                m++
            }
        }
    }
}

 

11.用堆排解决top_k问题,思路:

  a.先取前k个数建小根堆,这样就能保证堆顶元素是整个堆的最小值;

  b.然后遍历列表的k到最后,如果值比堆顶大,就和堆顶交换,交换完后再对堆建小根堆,这样就能保证交换完后,堆顶元素仍然是整个堆的最小值;

  c.一直遍历到列表的最后一个值,这一步做完之后,就保证了整个列表最大的前k个数已经放进了堆里;

  d.按数的大到小出堆;

func sift(li []int, low, high int) {
    i := low
    j := 2*i + 1
    tmp := li[i]
    for j <= high {
        if j < high && li[j] > li[j+1] {
            j++
        }
        if tmp > li[j] {
            li[i] = li[j]
            i = j
            j = 2*i + 1
        } else {
            break
        }
    }
    li[i] = tmp
}

func top_k(li []int, k int) []int {
    for i := k/2 - 1; i >= 0; i-- {
        sift(li, i, k-1)
    }
    for j := k; j < len(li); j++ {
        if li[0] < li[j] {
            li[0], li[j] = li[j], li[0]
            sift(li, 0, k-1)
        }
    }
    for n := k - 1; n > 0; n-- {
        li[0], li[n] = li[n], li[0]
        sift(li, 0, n-1)
    }
    return li[:k]
}

 

    原文作者:Coufusion
    原文地址: https://www.cnblogs.com/Coufusion/p/9804655.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞