【问题标题】:Error in heapsort algorithm堆排序算法错误
【发布时间】:2017-07-25 03:25:21
【问题描述】:

我正在尝试编写一个堆排序算法,这是我的代码。但是,它不起作用。当我尝试运行宏时,它说下标超出范围,它对应于if A(leftchild,1) > A(i,1) then 位。它说ileftchild 都等于零,但我不知道在哪里更改它。

Sub MakeMaxHeap(i As Long, heapsize As Long)
    Dim LeftChild As Long
    Dim RightChild As Long
    Dim largest As Long

    LeftChild = 2 * i
    RightChild = 2 * i + 1

    If heapsize > LeftChild Then
        If A(LeftChild, 1) > A(i, 1) Then
            largest = LeftChild
        ElseIf A(LeftChild, 1) = A(i, 1) Then
            largest = i
        End If
    End If

    If heapsize > RightChild Then
        If A(RightChild, 1) > A(largest, 1) Then
            largest = RightChild
        ElseIf A(RightChild, 1) = A(largest, 1) Then
            largest = i
        End If
    End If

    If largest <> i Then
        Call MakeMaxHeap(largest, heapsize)
    End If

End Sub

Sub BuildMaxHeap()
    Dim i As Long
    Dim heapsize As Long
    heapsize = n

    For i = n / 2 To 1 Step -1
        Call MakeMaxHeap(i, heapsize)
    Next i

End Sub


Sub HeapSort()
    Dim i As Long
    Dim temp As Double
    Dim j As Long
    Dim heapsize As Long

    Call InitializeA
    'This basically stores a
    Call BuildMaxHeap
    heapsize = n
    For i = n To 2 Step -1
        temp = A(i, 1)
        A(i, 1) = A(1, 1)
        A(1, 1) = temp
        heapsize = heapsize - 1
        Call MakeMaxHeap(1, heapsize)
    Next i

    For j = 1 To n
        Cells(j, 7).Value = A(j, 1)
    Next j
End Sub

【问题讨论】:

  • 变量An在哪里声明?它们在范围内是模块级别的吗?
  • 你需要在范围内声明n,这里不清楚它的值是什么。反过来,in 设置,并传递给MakeMaxHeap...这导致i 为0,所以LeftChild 为0...
  • @YowE3K A 和 N 被声明为全局变量
  • @Wolfie A 和 N 被声明为全局变量。 n 是单元格 B2 中给出的值

标签: algorithm excel sorting heapsort vba


【解决方案1】:

MakeMaxHeap 过程存在一些问题:

  • 在某些时候,变量largest 永远不会得到值,因为If 的两个条件都可能是False。如果发生这种情况,则使用第一个参数 0 进行递归调用,从而导致出现运行时错误。

  • 虽然进行了比较和递归调用,但MakeMaxHeap 实际上并没有改变数组的任何内容。应该交换值以使其成为最大堆。

这是 MakeMaxHeap 的更正代码,其中 cmets 进行了更改:

Sub MakeMaxHeap(i As Long, heapsize As Long)
    Dim LeftChild As Long
    Dim RightChild As Long
    Dim largest As Long
    Dim temp As Long ' *** Added

    LeftChild = 2 * i
    RightChild = 2 * i + 1

    ' *** Give the variable an initial value, as both If conditions might be false
    largest = i
    ' *** Use >= instead of >
    If heapsize >= LeftChild Then
        If A(LeftChild, 1) > A(i, 1) Then
            largest = LeftChild
        ' *** ElseIf is not needed
        End If
    End If

    ' *** Use >= instead of >
    If heapsize >= RightChild Then
        If A(RightChild, 1) > A(largest, 1) Then
            largest = RightChild
        ' *** ElseIf is not needed
        End If
    End If

    If largest <> i Then
        ' *** You need to actually swap the values
        temp = A(i, 1)
        A(i, 1) = A(largest, 1)
        A(largest, 1) = temp
        Call MakeMaxHeap(largest, heapsize)
    End If    
End Sub

【讨论】:

  • 好的,非常感谢,因为我确实注意到我的代码在 rand 时最大也等于 0,我知道它不起作用。代码几乎可以工作了,它只是显示的前 4 个值全为零,但其余的都是有序的
  • 是的,它现在确实有效,我只需要更改一些东西。非常感谢
猜你喜欢
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 2013-06-01
  • 2019-04-24
  • 2015-01-31
  • 2021-11-02
  • 2021-09-21
  • 1970-01-01
相关资源
最近更新 更多