forked from brogly-zz/randomstuff
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSortStuff.BAS
More file actions
212 lines (166 loc) · 5.37 KB
/
Copy pathSortStuff.BAS
File metadata and controls
212 lines (166 loc) · 5.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
Attribute VB_Name = "SortStuff"
'Sorting in VBA
Public QSortCalls As Integer
Public PartitionCalls As Integer
'Partition is part of QuickSort which puts numbers into
'a Less Than (L) Greater Than (G) or Equal (E) list.
Sub Partition(ByRef lst As Variant, ByRef l As Variant, ByRef e As Variant, ByRef g As Variant)
PartitionCalls = PartitionCalls + 1
If UBound(lst) = 0 Or UBound(lst) = 1 Then Exit Sub
Dim pivot As Integer
pivot = lst(UBound(lst) - 1)
For i = LBound(lst) To UBound(lst) - 1 Step 1
If lst(i) < pivot Then
ReDim Preserve l(UBound(l) + 1)
l(UBound(l) - 1) = lst(i)
ElseIf lst(i) = pivot Then
ReDim Preserve e(UBound(e) + 1)
e(UBound(e) - 1) = lst(i)
Else
ReDim Preserve g(UBound(g) + 1)
g(UBound(g) - 1) = lst(i)
End If
Next i
End Sub
'Main Quicksort Function
Function QSort(ByRef lst As Variant) As Variant
QSortCalls = QSortCalls + 1
If UBound(lst) = 0 Or UBound(lst) = 1 Then
QSort = lst
Exit Function
End If
Dim l() As Integer
ReDim l(0)
Dim e() As Integer
ReDim e(0)
Dim g() As Integer
ReDim g(0)
Partition lst, l, e, g
l = QSort(l)
e = QSort(e)
g = QSort(g)
Dim oldLUBound As Integer
oldLUBound = UBound(l)
ReDim Preserve l(UBound(l) + UBound(e) + UBound(g))
Dim i As Integer
For i = 0 To UBound(e) - 1 Step 1
l(i + oldLUBound) = e(i)
Next i
For i = 0 To UBound(g) - 1 Step 1
l(i + oldLUBound + UBound(e)) = g(i)
Next i
QSort = l
End Function
'Recursive Quick Sort. Fast!
'Seems to crash above 42 numbers. There could be a bug or the VBA Stack Space is very limited.
Sub QuickSortMain()
QSortCalls = 0
PartitionCalls = 0
Dim thingsToSort As Variant
thingsToSort = SortSheet.range("A1:A7").Value
Dim oneDArray As Variant
ReDim oneDArray(1)
Dim item As Variant
For Each item In thingsToSort
ReDim Preserve oneDArray(UBound(oneDArray) + 1)
oneDArray(UBound(oneDArray) - 1) = item
Next item
Dim startTime As Double
Dim finishTime As Double
Dim amtOfTime As Double
startTime = Timer
oneDArray = QSort(oneDArray)
finishTime = Timer
amtOfTime = finishTime - startTime
Debug.Print amtOfTime & " seconds."
SortSheet.range("B1:B7").Value = WorksheetFunction.Transpose(oneDArray)
MsgBox "QSortCalls: " & QSortCalls
MsgBox "PartitionCalls: " & PartitionCalls
End Sub
'Slow, because of the use of Cells
Sub Bogosort(ByVal amtOfNumbers As Integer, Optional screenUpdating As Boolean = True)
SortSheet.Activate
Application.screenUpdating = screenUpdating
Dim position As Integer
Dim sorted As Boolean
sorted = False
Do Until sorted = True
Dim i As Integer
For i = 1 To amtOfNumbers Step 1
position = Int((Rnd() * amtOfNumbers) + 1)
Dim tmp As Integer
tmp = SortSheet.Cells(i, 1)
SortSheet.Cells(i, 1) = SortSheet.Cells(position, 1)
SortSheet.Cells(position, 1) = tmp
Next i
sorted = True
For i = 2 To amtOfNumbers Step 1
If SortSheet.Cells(i - 1, 1) > SortSheet.Cells(i, 1) Then
sorted = False
End If
Next i
Loop
End Sub
'Fast, because of the use of Arrays
Sub BogosortArray(ByVal amtOfNumbers)
Dim numArray As Variant
numArray = SortSheet.range("A1:A" & amtOfNumbers).Value
SortSheet.Activate
Dim position As Integer
Dim sorted As Boolean
sorted = False
Do Until sorted = True
Dim i As Integer
For i = 1 To amtOfNumbers Step 1
position = Int((Rnd() * amtOfNumbers) + 1)
Dim tmp As Integer
tmp = numArray(i, 1)
numArray(i, 1) = numArray(position, 1)
numArray(position, 1) = tmp
Next i
sorted = True
For i = 2 To amtOfNumbers Step 1
If numArray(i - 1, 1) > numArray(i, 1) Then
sorted = False
End If
Next i
Loop
SortSheet.range("B1:B" & amtOfNumbers).Value = numArray
End Sub
'Bogosort, using Arrays (FAST!!!)
Sub BogosortFast()
Dim startTime As Double
Dim finishTime As Double
Dim amtOfTime As Double
startTime = Timer
BogosortArray 7
finishTime = Timer
amtOfTime = finishTime - startTime
Debug.Print amtOfTime & " seconds."
End Sub
'Sorting Speed Comparison:
'Cells With Screen Updating (default): 5.6875 seconds.
'Cells Without Screen Updating: 1.88671875 seconds.
'Array (Screen Updating not relevant): 0.03125 seconds.
'Quicksort (Screen Updating not relevant): 0 seconds.
'Bogosort, using Cells (Slooooow...)
Sub BogosortSlow()
Dim startTime As Double
Dim finishTime As Double
Dim amtOfTime As Double
startTime = Timer
Bogosort 7, False
finishTime = Timer
amtOfTime = finishTime - startTime
Debug.Print amtOfTime & " seconds."
End Sub
'Make some Random numbers to test sorting algorithms
Sub RandomNumbers()
RandomAColumn 500, 7
End Sub
Sub RandomAColumn(ByVal maxVal As Integer, ByVal amt As Integer)
Dim i As Integer
For i = 1 To amt
SortSheet.range("A" & i).Value = Int((Rnd * maxVal) + 1)
Next i
End Sub