MyTetra Share
Делитесь знаниями!
Сортировка
Время создания: 29.01.2021 16:03
Автор: Zheltov Alexey
Текстовые метки: Сортировка, sorting, array
Раздел: !Закладки - VBA - Excel - Листы - Фильтр-сортировка
Запись: xintrea/mytetra_db_adgaver_new/master/base/1611925381ttsj81s85m/text.html на raw.githubusercontent.com




Option Explicit


Const n As Long = 50

Dim Chrt As ChartObject


'**************************************************************

' Sub : Init

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Инициализация

'**************************************************************

Sub Init()

Set Chrt = ActiveSheet.ChartObjects(1)

End Sub


'**************************************************************

' Sub : RandomArray

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Перемешивание массива

'**************************************************************

Sub RandomArray()

Dim coll As New Collection

Dim rndVal As Long

Randomize

Do While coll.count < n

rndVal = CLng((n - 1) * Rnd) + 1

On Error Resume Next

coll.Add rndVal, CStr(rndVal)

If Err.Number = 0 Then Cells(1, coll.count) = rndVal

Err.Clear

Loop

End Sub


'**************************************************************

' Sub : StopSorting

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Остановка всех макросов

'**************************************************************

Sub StopSorting()

End

End Sub


'**************************************************************

' Sub : BubbleSort

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Сортировка простыми обменами, сортировка пузырьком

'**************************************************************

Sub BubbleSort()


Dim i As Long

Dim j As Long

Dim Flag As Boolean

Init

For i = 1 To n - 1

Flag = False

For j = 1 To n - i

If Cells(1, j) > Cells(1, j + 1) Then Swap Cells(1, j), Cells(1, j + 1): Flag = True

Next

If Not Flag Then Exit For

Next


End Sub



'**************************************************************

' Sub : ShakerSort

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Сортировка перемешиванием или Шейкерная сортировка

' или двунаправленная (англ. Cocktail sort) — разновидность пузырьковой сортировки

'**************************************************************

Sub ShakerSort()

Dim left As Long

Dim right As Long

Dim count As Long

Dim i As Long

Init

left = 1

right = n

count = 0

Do While left < right

For i = left To right - 1

count = count + 1

If Cells(1, i) > Cells(1, i + 1) Then Swap Cells(1, i), Cells(1, i + 1)

Next

right = right - 1

For i = right To left + 1 Step -1

count = count + 1

If Cells(1, i - 1) > Cells(1, i) Then Swap Cells(1, i - 1), Cells(1, i)

Next

left = left + 1

Loop

End Sub

'**************************************************************

' Sub : InsertionSort

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Сортировка вставками

'**************************************************************

Sub InsertionSort()

Dim i As Long

Dim j As Long

Init

For i = 2 To n

j = i

Do While j > 1

If Cells(1, j) > Cells(1, j - 1) Then Exit Do

Swap Cells(1, j), Cells(1, j - 1)

j = j - 1

Loop

Next

End Sub


'**************************************************************

' Sub : GnomeSort

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Гномья сортировка

'**************************************************************

Sub GnomeSort()

Dim i As Long

Dim j As Long

Init

i = 2

j = 2

Do While i < n + 1

If Cells(1, i - 1) < Cells(1, i) Then

i = j

j = j + 1

Else

Swap Cells(1, i - 1), Cells(1, i)

i = i - 1

If i = 1 Then

i = j

j = j + 1

End If

End If

Loop

End Sub


'**************************************************************

' Sub : BubbleSortWhithInsertion

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Объединение сортировки пузырьком и сортировки выбором

'**************************************************************

Sub BubbleSortWhithSelection()

Dim i As Long

Dim j As Long

Dim iMin As Long


Init

For i = 1 To n - 1

iMin = i

For j = i To n - i

If Cells(1, j) > Cells(1, j + 1) Then Swap Cells(1, j), Cells(1, j + 1)

If Cells(1, j) < Cells(1, iMin) Then iMin = j

Next

If iMin <> i Then Swap Cells(1, i), Cells(1, iMin)

Next


End Sub


'**************************************************************

' Sub : StartMergeSort

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Запуск сортировки слиянием

'**************************************************************

Sub StartMergeSort()

Init

MergeSort Range(Cells(1, 1), Cells(1, n))

End Sub


'**************************************************************

' Function : MergeSort

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Рекурсивная функция сортировки слиянием

'**************************************************************

Function MergeSort(rng As Range)

Dim left As Range

Dim right As Range

Dim result As Range

Dim i As Long

Dim middle As Long

If rng.Cells.count = 1 Then

Set MergeSort = rng

Exit Function

Else

middle = CLng(rng.Cells.count / 2)

' Разделяем диапазон на 2 части

Set left = Range(rng.Columns(1), rng.Columns(middle))

Set right = Range(rng.Columns(middle + 1), rng.Columns(rng.Columns.count))


' Рекурсивно проходим этой же функцией по каждой части

left = MergeSort(left)

right = MergeSort(right)

' Объединяем части обратно в единое целое

MergeSort = Merge(left, right)

End If

End Function


'**************************************************************

' Function : Merge

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Функция сортирует и объединяет диапазон

'**************************************************************

Function Merge(left As Range, right As Range) As Range

Dim i As Long

Dim count As Long

Dim result

Dim sizeLeft As Long

Dim sizeRight As Long

Dim FirstRng As Range

Set FirstRng = left.Cells(1, 1)

sizeLeft = left.count

sizeRight = right.count

ReDim result(1 To sizeLeft + sizeRight)

i = 1

Do While sizeLeft > 0 And sizeRight > 0

If left.Columns(1) <= right.Columns(1) Then

result(i) = left.Columns(1)

If sizeLeft > 1 Then Set left = left.Offset(, 1).Resize(, left.Columns.count - 1)

sizeLeft = sizeLeft - 1

Else

result(i) = right.Columns(1)

If sizeRight > 1 Then Set right = right.Offset(, 1).Resize(, right.Columns.count - 1)

sizeRight = sizeRight - 1

End If

i = i + 1

Loop

Do While sizeLeft > 0

result(i) = left.Columns(1)

If sizeLeft > 1 Then Set left = left.Offset(, 1).Resize(, left.Columns.count - 1)

sizeLeft = sizeLeft - 1

i = i + 1

Loop

Do While sizeRight > 0

result(i) = right.Columns(1)

If sizeRight > 1 Then Set right = right.Offset(, 1).Resize(, right.Columns.count - 1)

sizeRight = sizeRight - 1

i = i + 1

Loop


For i = 1 To UBound(result)

FirstRng.Offset(, i - 1) = result(i)

ChartRefresh

Next

Set Merge = FirstRng.Resize(, UBound(result))

End Function


'**************************************************************

' Sub : StartQuickSort

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Запуск быстрой сортировки

'**************************************************************

Sub StartQuickSort()

Init

QuickSort Range(Cells(1, 1), Cells(1, n)), 1, n

End Sub


'**************************************************************

' Sub : QuickSort

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Рекурсивная функция для быстрой сортировки

'**************************************************************

Sub QuickSort(rng As Range, lo, hi)

Dim p As Long

If lo < hi Then

p = Partition(rng, lo, hi)

Call QuickSort(rng, lo, p)

Call QuickSort(rng, p + 1, hi)

End If

End Sub


'**************************************************************

' Function : Partition

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Выбор опорного элемента для быстрой сортировки

'**************************************************************

Function Partition(rng As Range, lo, hi)

Dim i As Long

Dim j As Long

Dim pivot

i = lo

j = hi

pivot = (rng.Cells(1, lo) + rng.Cells(1, hi)) / 2

Do

Do While rng.Cells(1, i) < pivot

i = i + 1

Loop

Do While rng.Cells(1, j) > pivot

j = j - 1

Loop

If i >= j Then

Partition = j

Exit Function

End If

Swap rng.Cells(1, i), rng.Cells(1, j)

Loop


End Function


'**************************************************************

' Sub : SelectionSort

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Сортировка выбором

'**************************************************************

Sub SelectionSort()

Dim i As Long

Dim j As Long

Dim iMin As Long


Init

For i = 1 To n

iMin = i

For j = i To n

If Cells(1, j) < Cells(1, iMin) Then iMin = j

Next

If iMin <> i Then Swap Cells(1, i), Cells(1, iMin)

Next


End Sub


'**************************************************************

' Sub : HeapSort

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Пирамидальная сортировка

'**************************************************************

Sub HeapSort()

Dim i As Long

Dim j As Long

Init


For i = 1 To n

For j = CInt((n + 1) / 2) - CInt(i / 2) To 1 Step -1

If 2 * j + 1 <= n - i + 1 Then

If Cells(1, 2 * j) > Cells(1, 2 * j + 1) Then

If Cells(1, j) < Cells(1, 2 * j) Then

Swap Cells(1, j), Cells(1, 2 * j)

End If

Else

If Cells(1, j) < Cells(1, 2 * j + 1) Then

Swap Cells(1, j), Cells(1, 2 * j + 1)

End If

End If

Else

If 2 * j <= n - i + 1 Then

If Cells(1, j) < Cells(1, 2 * j) Then

Swap Cells(1, j), Cells(1, 2 * j)

End If

End If

End If

Next

Swap Cells(1, 1), Cells(1, n - i + 1)

Next

End Sub


'**************************************************************

' Sub : Swap

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Перестановка ячеек

'**************************************************************

Sub Swap(A As Range, B As Range)

Dim C As String

C = A

A = B

B = C

ChartRefresh

End Sub


'**************************************************************

' Sub : ChartRefresh

' Author : Zheltov Alexey

' Date : 24.12.2020

' Purpose : Обновление диаграммы

'**************************************************************

Sub ChartRefresh()

Chrt.Activate

Application.Calculate

DoEvents

End Sub


 
MyTetra Share v.0.59
Яндекс индекс цитирования