堆排序

代码实现

type hp []int

func (h *hp) Init(arr []int) {
    n := len(arr)
    *h = make([]int, n)
    copy(*h, arr)
    for i := n/2 - 1; i >= 0; i-- {
        h.down(i, n)
    }
}

func (h *hp) Push(num int) {
    *h = append(*h, num)
    h.up(len(*h) - 1)
}

func (h *hp) Pop() int {
    v := (*h)[0]
    n := len(*h) - 1
    (*h)[0], (*h)[n] = (*h)[n], (*h)[0]
    h.down(0, n)
    *h = (*h)[:n]
    return v
}

func (h *hp) up(i int) {
    for {
        j := (i - 1) / 2 // 父节点
        if i == j || (*h)[j] <= (*h)[i] {
            break
        }

        // 交换两个节点
        (*h)[j], (*h)[i] = (*h)[i], (*h)[j]
        i = j
    }
}

func (h *hp) down(i, n int) {
    for {
        j1 := i*2 + 1
        if j1 >= n || j1 < 0 {
            break
        }

        // 找到比较小的那个节点
        j := j1 // 左节点
        if j2 := j1 + 1; j2 < n && (*h)[j2] < (*h)[j1] {
            j = j2 // 右节点
        }

        // 如果比最小的节点还小,结束下沉
        if (*h)[i] < (*h)[j] {
            break
        }

        // 交换两个节点的值,赋值要下沉节点的新位子
        (*h)[i], (*h)[j] = (*h)[j], (*h)[i]
        i = j
    }
}

func main() {
    ax := []int{7, 6, 7, 6, 9}
    h1.Init(ax)
    h1.Push(0)
    h1.Push(54)
    h1.Push(4)
    for i := 0; i < len(ax)+3; i++ {
        fmt.Print(h1.Pop(), " ")
    }
    return
}

输出结果:0 4 6 6 7 7 9 54

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容