Сортировка бинарным деревом - VBA
Формулировка задачи:
Подсмотрел я тут методы и подумал - а почему бы не написать на VBA сорировку методом бинарного дерева? Общий алгоритм сортировки был на википедии, так что оставалось всего лишь написать код. В ходе кровь из носу потребовалось ознакомиться с такой штукой как классы, о которой я ранее не имел ни малейшего представления.
По итогам длительных мучений: сортировать этот зверь, конечно, сортирует, но уже на 100k чисел типа Double у него уходит немалое время (порядка нескольких секунд на моем не самом резвом рабочем компьютере). К тому же в коде есть ряд шероховатостей -
1) метод Retrieve, получающий значения из уже сформированного дерева, как я с ним не бился, оставляет пустую строчку в начале или в конце массива. Работать со счетчиками он при этом решительно отказывается, так что пришлось плюнуть и просто после его отработки делать еще один Redim Preserve
2) тот же многострадальный метод Retrieve работает с внешней переменной, получаемой ByRef. В нее он записывает значения, что, насколько я знаю, не очень хорошо.
Возможно, есть еще какие-то ошибки, которые я не заметил.
Просьба к уважаемым форумчанам покритиковать решение. Здесь привожу код самого класса и процедур, с ним работающих.
Решение задачи: «Сортировка бинарным деревом»
textual
Листинг программы
'::: Пирамидальная сортировка (Главная процедура) Sub HeapSort(X() As Double) Dim Heap() As Double Dim N& Dim HeapSize& Dim I& N& = UBound(X, 1) ReDim Heap(1 To N) As Double '::: Занесение в пирамиду HeapSize& = 1 Heap(1) = X(1) For ii& = 2 To N HeapSize& = HeapSize& + 1 Heap(HeapSize&) = X(ii&) ptr& = HeapSize& pUp Heap(), ptr& Next ii& '::: Вывод отсортированного o& = N Do If HeapSize& = 0 Then Exit Do X(o&) = Heap(1) o& = o& - 1 Swap Heap(1), Heap(HeapSize&) HeapSize& = HeapSize& - 1 pDown Heap(), 1, HeapSize& Loop End Sub ':::: Просеивание вверх Sub pUp(Heap() As Double, p As Long) If p = 1 Then Exit Sub Par& = p \ 2 If Heap(p) <= Heap(Par&) Then Exit Sub Swap Heap(p), Heap(Par&) pUp Heap(), Par& End Sub ':::: Просеивание вниз Sub pDown(Heap() As Double, p As Long, HeapSize As Long) If (2 * p) >= HeapSize Then Exit Sub ZL# = Heap(2 * p) ZR# = Heap(2 * p + 1) If (Heap(p) >= ZL#) And (Heap(p) >= ZR#) Then Exit Sub If (ZL# >= ZR#) Then Swap Heap(p), Heap(2 * p) pDown Heap(), 2 * p, HeapSize Else Swap Heap(p), Heap(2 * p + 1) pDown Heap(), 2 * p + 1, HeapSize End If End Sub ':::: Обменять два элемента Sub Swap(a As Double, B As Double) tmp# = a a = B B = tmp# End Sub ':::: Стартовая процедура Sub Test() Dim I&, t! Dim H(1 To 800000) As Double, Q(1 To 800000) As Double For I = 1 To UBound(H) H(I) = Rnd Q(I) = H(I) Next I t = Timer HeapSort H() Debug.Print "HeapSort t="; Timer - t t = Timer QuickSort Q(), LBound(Q), UBound(Q) Debug.Print "QuickSort t="; Timer - t 'и проверить решил на всякий случай For I = 1 To UBound(H) If H(I) <> Q(I) Then Stop Next I End Sub Sub QuickSort(a() As Double, ByVal L As Long, ByVal U As Long) Dim I As Long, J As Long, X As Double, Y As Double I = L: J = U: X = a((L + U) \ 2) Do While a(I) < X: I = I + 1: Wend: While X < a(J): J = J - 1: Wend 'по возрастанию ' While A(I) > X: I = I + 1: Wend: While X > A(J): J = J - 1: Wend 'по убыванию If I <= J Then Y = a(I): a(I) = a(J): a(J) = Y: I = I + 1: J = J - 1 End If Loop Until I > J If L < J Then QuickSort a, L, J If I < U Then QuickSort a, I, U End Sub
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д