go语言 堆排序

算法思想: 数组构成堆
算法步骤:
用数列构建出一个大顶堆,取出堆顶的数字;
调整剩余的数字,构建出新的大顶堆,再次取出堆顶的数字;
循环往复,完成整个排序。
是否稳定:
算法时间复杂度: O(nlogn)
难点: 构建大顶堆 & 调整堆
构建大顶堆有两种方式:
方案一: 从 0 开始,将每个数字依次插入堆中,一边插入,一边调整堆的结构,使其满足大顶堆的要求;
方案二: 将整个数列的初始状态视作一棵完全二叉树,自底向上调整树的结构,使其满足大顶堆的要求。

完全二叉树的几个性质:将根节点的下标视为 0 对于完全二叉树中的第 i 个数,它的左子节点下标:left = 2i + 1
对于完全二叉树中的第 i 个数,它的右子节点下标:right = left + 1 对于有 n
个元素的完全二叉树(n≥2)(n≥2),它的最后一个非叶子结点的下标:n/2 - 1

方案二更加常用:代码:

func heapSort(arr []int){ //arr.length = n
    //构建大根堆
    buildMaxHeap(arr)
    //排序 n-1 次
    for(i:=arr.length - 1; i > 0; i--){
        swap(arr, 0, i) // 将最大值交换到数组最后
        maxHeapify(arr, 0, i); //调整交换后的结点
    }
}
构建大根堆 代码:
func buildMaxHeap(arr []int){
    从最后一个非叶子节点开始调整大根堆
    最后一个非叶子节点为 arr.length/2 - 1
    for (int i = arr.length / 2 - 1; i >= 0; i--) {
        maxHeapify(arr, i, arr.length);
    }
}
调整大顶堆 代码:
func maxHeapify(arr []int, i, haepSize int){ //i:要进行调整为堆的非叶子节点结点,heapSize:堆的大小
    //左子树下标
    l := 2 * i + 1
    //右子树下标
    r := l + 1
    // 记录根结点、左子树结点、右子树结点三者中的最大值下标
    largest := i
    if(l < heapSize && arr[l] > arr[largest]){
        largest = l  
    }
    if(r < heapSize && arr[r] > arr[largest]){
        largest = r   
    }
    if(i != largest){
        //交换位置
        swag(arr, i, largest)
        // 再次调整交换数字后的大顶堆
        maxHeapify(arr, largest, heapSize)
    }
}
func swap(arr []int, int i, int j) {
    temp := arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值