• go 堆排序


    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	heap := BuildHeap([]int{33, 24, 8, 3, 1001, 15, 16, 15, 30, 17, 19})
    	var sortedArr []int
    	for  {
    		v,ok := heap.Pop()
    		if !ok {
    			break
    		}
    		sortedArr = append(sortedArr, v)
    	}
    
    	fmt.Println(sortedArr)
    }
    
    // 小顶堆(完全二叉树,最下面一层的节点都集中在该层最左边的连续位置上;父节点小于子节点;所以可以用数组存放)
    // 存储结构:i 为下标, 左子节点 i*2+1, 右子节点 i*2+2, 父节点 (i-1)/2
    
    type Heap []int
    
    // 交换位置
    func (h Heap) swap(i, j int) {
    	h[j], h[i] = h[i], h[j]
    }
    
    // 比较节点大小
    func (h Heap) less(i, j int) bool {
    	return h[i] < h[j]
    }
    
    // 插入
    // 首先插入最末尾节点,自下而上与父节点比较,不断上升,一直到满足小顶堆规则
    // 两种情况:1.一直升到堆顶;2.到某一位置时发现父节点比自己小,则停止。
    func (h Heap) up(i int) {
    	for {
    
    		f := (i - 1) / 2
    
    		// 停止
    		if i == f || h.less(f, i) {
    			break
    		}
    
    		// 上升
    		h.swap(f, i)
    		i = f
    	}
    }
    
    func (h *Heap) Push(i int) {
    	*h = append(*h, i)
    	h.up(len(*h) - 1)
    }
    
    // 删除
    // 1.将末节点和删除节点交换,然后删除末尾节点
    // 2.原末端节点需要与新位置上的父节点做比较,如果小于要做 up(看上面的方法),
    // 如果大于父节点,则再和子节点做比较,即 down 操作,直到该节点下降到小于最小子节点为止。与最小的子节点交换
    func (h Heap) down(i int) {
    	for {
    		lson := i*2 + 1
    		rson := i*2 + 2
    
    		if rson >= len(h) {
    			break
    		}
    
    		if h.less(i, lson) && h.less(i, rson) {
    			break
    		}
    		if h.less(lson, rson) {
    			h.swap(i, lson)
    			i = lson
    		} else {
    			h.swap(i, rson)
    			i = rson
    		}
    
    	}
    }
    
    func (h *Heap) Remove(i int) (int, bool) {
    	if i < 0 || i > len(*h)-1 {
    		return 0, false
    	}
    	// 交换
    	tail := len(*h) - 1
    	h.swap(tail, i)
    	// 删除最后元素
    	x := (*h)[tail]
    	*h = (*h)[:tail]
    
    	// i节点下降或者上升
    	if i == 0 || (*h)[i] > (*h)[(i-1)/2] {
    		h.down(i)
    	} else {
    		h.up(i)
    	}
    	return x, true
    }
    
    // 弹出顶点
    func (h *Heap) Pop() (int, bool) {
    	return h.Remove(0)
    }
    
    // 建堆
    // 自底向上调整,不断的将最小值向上推。倒数第二层开始,从右到左
    func BuildHeap(arr []int) Heap {
    	h := Heap(arr)
    	last := len(arr) - 1
    	// 最后节点的父节点
    	for i := (last - 1) / 2; i >= 0; i-- {
    		h.down(i)
    	}
    	return h
    }
    
    
  • 相关阅读:
    内置函数
    win10 下安装meteror
    每日十问(3)
    白话带你理解什么是编程
    什么是对象的方法
    Python之列表推导式
    英语对学习软件开发重要吗?
    python3中的range函数返回的是列表吗?
    文件读写
    神奇的字符编码
  • 原文地址:https://www.cnblogs.com/fanzou/p/16173448.html
Copyright © 2020-2023  润新知