Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 7
Default alfabetical order in array

I have dinamic array.
All the elements are diffrent.
Question ? how to sort them in alfabetical order.

Of course you can put data into sheet, sort and reload the
array but it takes time so maybe somebody knows better
solutions.

Tks
  #2   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 27,285
Default alfabetical order in array

This this post by Keith Willshaw was meant for you:

There's a nice quicksort routine on Stephen Bullen's page

http://www.bmsltd.co.uk/Excel/SBXLPage.asp

Keith

--
Regards,
Tom Ogilvy

"Konrad" wrote in message
...
I have dinamic array.
All the elements are diffrent.
Question ? how to sort them in alfabetical order.

Of course you can put data into sheet, sort and reload the
array but it takes time so maybe somebody knows better
solutions.

Tks



  #3   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 20
Default alfabetical order in array

QuickSort is usually a fast algorithm, but can degrade to O(N^2)
behavior (i.e., require time proportional to the square of the number of
items sorted) under certain conditions. The QuickSort on Steve Bullen's
page does not contain the optimization (median of three partitioning)
needed to make such misbehavior unlikely. QuickSort is also unstable --
sorting on each field of a record will lose any ordering based on
previous fields.

MergeSort is almost as fast as QuickSort, but is guaranteed always to
sort in O(N log N) time, no matter what. Furthermore, it's stable; if
you sort on field A and then field B, records with the same value of
field B will remain sorted as to field A. Because of its stability and
consistent performance, MergeSort is often used for system sorts. Its
one drawback is the need for an extra array for the merge operations.

The following code will sort an array of variants into ascending order.
It works by dividing the array into short runs, sorting them by
InsertionSort (the most efficient sort for short lists) and then merging
pairs of runs until only a single run is left.

It's long but fast, and less complicated than it looks.

Dave Ring

Sub MergeSort(A())
Dim B(), Length&, nRuns&, Stack() As Long
Dim I&, L&, R&, LP&, RP&, OP&, TMP

Length = UBound(A)
ReDim B(1 To Length)
nRuns = 1

'Divide the array into short runs
While Length 20
Length = Length / 4
nRuns = nRuns * 4
Wend
ReDim Stack(1 To nRuns)
For I = 1 To nRuns - 1
Stack(I) = 1 + (Length * CDbl(I))
Next I
Stack(nRuns) = Length

'Sort the short runs by InsertionSort
L = 1
For I = 1 To nRuns
R = Stack(I)
For RP = L + 1 To R
TMP = A(RP)
For LP = RP - 1 To L Step -1
If TMP < A(LP) Then A(LP + 1) = A(LP) Else Exit For
Next LP
A(LP + 1) = TMP
Next RP
L = R + 1
Next I

'Merge pairs of runs until only one is left
While nRuns 1
'Forward merge from array A to auxiliary array B
R = 0
For I = 2 To nRuns Step 2
LP = R + 1
OP = LP
L = Stack(I - 1)
RP = L + 1
R = Stack(I)
Do
If A(LP) <= A(RP) Then
B(OP) = A(LP)
OP = OP + 1
LP = LP + 1
If LP L Then
Do
B(OP) = A(RP)
OP = OP + 1
RP = RP + 1
Loop Until RP R
Exit Do
End If
Else
B(OP) = A(RP)
OP = OP + 1
RP = RP + 1
If RP R Then
Do
B(OP) = A(LP)
OP = OP + 1
LP = LP + 1
Loop Until LP L
Exit Do
End If
End If
Loop
Stack(I \ 2) = R
Next I
nRuns = nRuns \ 2

'Backward merge from auxiliary array B to A
R = 0
For I = 2 To nRuns Step 2
LP = R + 1
OP = LP
L = Stack(I - 1)
RP = L + 1
R = Stack(I)
Do
If B(LP) <= B(RP) Then
A(OP) = B(LP)
OP = OP + 1
LP = LP + 1
If LP L Then
Do
A(OP) = B(RP)
OP = OP + 1
RP = RP + 1
Loop Until RP R
Exit Do
End If
Else
A(OP) = B(RP)
OP = OP + 1
RP = RP + 1
If RP R Then
Do
A(OP) = B(LP)
OP = OP + 1
LP = LP + 1
Loop Until LP L
Exit Do
End If
End If
Loop
Stack(I \ 2) = R
Next I
nRuns = nRuns \ 2
Wend
End Sub

Konrad wrote:
I have dinamic array.
All the elements are diffrent.
Question ? how to sort them in alfabetical order.

Of course you can put data into sheet, sort and reload the
array but it takes time so maybe somebody knows better
solutions.

Tks


  #4   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 124
Default alfabetical order in array

And, for others who are interested in seeing how a merge sort works, I've rewritten Dave's
routine, splitting it into 4 separate Subs -- the main one, which calls the other 3. They are
(1) a routine to set up the stack array (I called it Ptrs()), (2) the insertion sort code, and
(3) the code to merge two adjacent segments into one. And I modified things to work with arrays
that have a lower bound other than 1.

As Dave mentioned in our email correspondence, in-line code undoubtedly runs faster than
separate subs, but the latter are easier to decipher.

I changed the array type from variant to double. The consequence of that is you need separate
code for sorting each data type. But I prefer that, because variants are inherently slow to work
with.

Option Explicit

Sub MergeSort(Ary() As Double)
'Based on code from Dave Ring, 08/15/2003,
Dim i As Long
Dim j As Long
Dim NumSegs As Long
Dim Ptrs() As Long
Dim Tmp() As Double

i = LBound(Ary)
j = UBound(Ary)
ReDim Tmp(i To j)

'partition the array into small segments with
'pointers to end of each segment in Ptrs()
NumSegs = MakePtrs(i, j, Ptrs())

'sort each segment with InsertionSort
For i = 1 To NumSegs
InsertionSort Ary(), Ptrs(i - 1) + 1, Ptrs(i)
Next i

'merge pairs of segments until only one is left
Do While NumSegs 1
For i = 2 To NumSegs Step 2
MergeSegments Ary(), Tmp(), _
Ptrs(i - 2) + 1, Ptrs(i - 1), Ptrs(i - 1) + 1, Ptrs(i)
Ptrs(i \ 2) = Ptrs(i)
Next i
NumSegs = NumSegs \ 2

For i = 2 To NumSegs Step 2
MergeSegments Tmp(), Ary(), _
Ptrs(i - 2) + 1, Ptrs(i - 1), Ptrs(i - 1) + 1, Ptrs(i)
Ptrs(i \ 2) = Ptrs(i)
Next i
NumSegs = NumSegs \ 2
Loop
End Sub

Private Function MakePtrs(Lo As Long, Hi As Long, Ptrs() As Long) As Long
'modified to handle arrays with lower bound < 1
Dim i As Long
Dim Size As Double
Dim NumSegs As Long
Dim N As Long

Size = Hi - Lo + 1
NumSegs = 1
Do While Size 20
Size = Size / 4
NumSegs = NumSegs * 4
Loop

'fill array with pointer to last element in each segment
ReDim Ptrs(0 To NumSegs)
Ptrs(0) = Lo - 1
Ptrs(NumSegs) = Hi
For i = 1 To NumSegs - 1
Ptrs(i) = i * Size + Lo - 1
Next i
MakePtrs = NumSegs
End Function

Sub InsertionSort(Ary() As Double, Lo As Long, Hi As Long)
Dim i As Long
Dim j As Long
Dim Tmp As Double

For i = Lo + 1 To Hi
Tmp = Ary(i)
For j = i - 1 To Lo Step -1
If Tmp < Ary(j) Then
Ary(j + 1) = Ary(j)
Else
Exit For
End If
Next j
Ary(j + 1) = Tmp
Next i
End Sub

Private Sub MergeSegments(Src() As Double, Dest() As Double, _
LeftFirst As Long, LeftLast As Long, RightFirst As Long, RightLast As Long)
Dim L As Long
Dim R As Long
Dim p As Long

L = LeftFirst
R = RightFirst
p = L - 1

Do
If Src(L) <= Src(R) Then
p = p + 1
Dest(p) = Src(L)

If L = LeftLast Then
For R = R To RightLast
p = p + 1
Dest(p) = Src(R)
Next R
Exit Do
Else
L = L + 1
End If

Else
p = p + 1
Dest(p) = Src(R)

If R = RightLast Then
For L = L To LeftLast
p = p + 1
Dest(p) = Src(L)
Next L
Exit Do
Else
R = R + 1
End If
End If
Loop
End Sub


Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules

Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
search an array in reverse (bottom to top) order Trainer_00 Excel Discussion (Misc queries) 5 December 20th 07 10:35 PM
Transpose and order array numbers cradino Excel Worksheet Functions 2 October 1st 05 06:27 PM
How do I lookup a value in a array that is not in ascending order John Excel Worksheet Functions 6 June 20th 05 09:40 PM
Excel; vba; listbox how to reorganize list in alfabetical order Konrad Excel Programming 1 August 7th 03 03:50 AM
Randomize the order of the contents of an array Lee Wold Excel Programming 3 July 12th 03 07:12 PM


All times are GMT +1. The time now is 11:17 AM.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Copyright ©2004-2025 ExcelBanter.
The comments are property of their posters.
 

About Us

"It's about Microsoft Excel"