算法4 vba实现堆排序

前言:只有自己取亲自尝试,才知道坑有多少,一个细节没注意,都会导致整个结果的错误,泪奔。

' 堆排序

Sub main()

    Dim a() As Variant
    
    a = Array(1, 5, 2, 5, 0, 4, 8)
    
    heapSort a

End Sub

' 封闭了数组操作,可以很安全的从1 开始
Sub heapSort(a() As Variant)

    
    Dim i As Integer
    
    Dim num As Integer
    
    ' 数组长度为num,从1-num
    num = UBound(a) + 1
    
    
    ' 构建堆有序,升序,需要采用删除的方式,所以,需要寻找最大数值放于末尾,构建最大堆,
    ' 我们总是把根节点和尾节点交换,并让根节点再次下沉,以此来进行排序
    For i = Int(num / 2) To 1 Step -1
        sink a, i, num
    Next
    
    Dim k As Integer
    
    k = num
    
    ' 使用删除的方式,来排序,尾部已经确认,所以不参与
    ' 为什么=1不参与排序?
    ' k = 1 已经越界了
    While k > 1
        exch a, 1, k
        k = k - 1
        sink a, 1, k
    Wend

End Sub

Sub sink(a() As Variant, n As Integer, num As Integer)
    
    ' 准备下沉位置
    Dim j As Integer
    
    ' 当前索引
    Dim i As Integer
    
    i = n
    
    While i <= Int(num / 2)
        ' 注意,如果i=0,是会陷入死循环的,这是一个坑
        j = 2 * i
        
        '  防止越界,所以才做判断,如果 j = num ,依然可以比较并交换
        
        If j < num Then
            ' 如果有两个节点,就可以这么操作,如果没有,这个步骤就可以省略了
            ' 这里关注更大,要满足稳定状态,两个子节点都比自身小,和更大的交换,才能稳定
            ' 取决于根节点的选取
            If less(a, j, j + 1) Then j = j + 1

        End If
        ' 注意,即使j=num,依然可以比较并交换,不要写入上面if
        ' 检查是否稳定,如果自身比最大的还大或者相等,状态已经稳定
        If not less(a, i, j) Then Exit Sub
        
        exch a, j, i
        
        i = j
    Wend
    
End Sub


' ----------封闭数组操作,可以隔离索引关系,比如数组是0 - 9,外层操作可以改为1-10 ,更加直观,方便----------

Private Function less(a() As Variant, i As Integer, j As Integer)
    less = a(i - 1) < a(j - 1)
End Function




Sub exch(a() As Variant, i As Integer, j As Integer)
    Dim temp
    
    temp = a(i - 1)
    
    a(i - 1) = a(j - 1)
    
    a(j - 1) = temp
End Sub


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值