前提・実現したいこと
マージソートでソート済みの数値を出力したいです。
発生している問題・エラーメッセージ
エラーはございません。
該当のソースコード
VBA
1Option Explicit 2 3Dim A() As Variant '配列Aをグローバル変数にしました 4Dim n As Long 'n個の配列Aを作る 5Dim L() As Variant 6Dim R() As Variant 7Dim cnt As Long 'ファンクションmergeにおける比較回数の総数 8 9'得られた2つのソート済み部分配列をmergeにより「統合」 10Function merge(A() As Variant, n As Long, left As Long, mid As Long, right As Long) 11 Dim n1 As Long 12 Dim n2 As Long 13 Dim i As Long 14 Dim j As Long 15 Dim k As Long 16 17 n1 = mid - left 18 n2 = right - mid 19 20 ReDim L(mid - left) 21 ReDim R(right - mid) 22 23 For i = 0 To n1 - 1 24 L(i) = A(left + i) 25 Next i 26 For i = 0 To n2 - 1 27 R(i) = A(mid + i) 28 Next i 29 30 i = 0 31 j = 0 32 For k = left To right - 1 33 cnt = cnt + 1 34 If L(i) <= R(i) Then 35 A(k) = L(i + 1) 36 Else 37 A(k) = R(j + 1) 38 End If 39 Next k 40 Erase L 41 Erase R 42End Function 43 44 45'指定されたn個の要素を含む部分配列をそれぞれn/2の要素を含む2つの部分配列に分割する 46'その2つの部分配列をそれぞれmergeSortでソートする 47Function mergeSort(A() As Variant, n As Long, left As Long, right As Long) 48 If (left + 1) < right Then 49 Dim mid As Long 50 mid = (left + right) / 2 51 Call mergeSort(A, n, left, mid) 52 Call mergeSort(A, n, mid, right) 53 Call merge(A, n, left, mid, right) 54 End If 55End Function 56 57Sub main() 58 Dim i As Long 59 60 cnt = 0 61 62 A = Array(8, 5, 9, 2, 6, 3, 7, 1, 10, 4) 63 64 n = UBound(A) + 1 65 66 Call mergeSort(A, n, 0, n) 67 68 For i = 0 To UBound(A) 69 Debug.Print A(i) 70 Next 71 72 Debug.Print cnt 73End Sub
試したこと
ヴァリアント型の配列Aをグローバル変数にしました。そうすることでmergeSortでソートされた配列AがDebug.Printで表示されると思ったのですが上手くいきませんでした。
補足情報(FW/ツールのバージョンなど)
変数cntはmergeファンクションにおける比較回数の総数を表しています。
Microsoft Excel 2016
> 上手くいきませんでした
なにが/どのように"上手くいきませんでした"なのか、説明してください。
epsteme様
ありがとうございます。
配列変数Aをグローバル変数にすれば変数の適用範囲が広がりファンクションmergeSortやファンクションmergeでの配列変数Aの処理をmainに渡せると思いました。でもmergeにおけるっ比較回数は上手く表示されるのですが、「ファンクションmergeSortでソートされた数値」が全く表示されませんでした。
> 配列変数Aをグローバル変数にすれば変数の適用範囲が広がりファンクションmergeSortやファンクションmergeでの配列変数Aの処理をmainに渡せると思いました。
そのアイデアが正しいか、確認しましたか?
episteme様
ありがとうございます。
デバッグするとファンクションmergeの
For k = left To right - 1
cnt = cnt + 1
If L(i) <= R(i) Then
A(k) = L(i + 1)
Else
A(k) = R(j + 1)
End If
Next k
のところで A(k) = L(i + 1)もA(k) = R(j + 1)も共にempty値になってしまいます。