Rutinas para clasificar un array en memoria

Primera: 7/Ago/97


Incluyo CUATRO rutinas para clasificar un array.
Iba a poner s�lo una, la que yo he estado usando durante a�os, pero me decid� a incluir la que ven�a con uno de los ejemplos del QuickBasic, creo que esta era la que llaman QuickSort, no he encontrado otro archivo que inclu�a varias rutinas de clasificaci�n, si alg�n d�a las localizo, estar�n en los discos de instalaci�n, las pondr� para que decidas cual quieres usar.

La rutina que yo he estado usando, realmente no clasifica el Array que contiene los datos, en su lugar lo que hace es clasificar un array de punteros... Estos punteros indican la posici�n clasificada. De esta forma no se cambia el orden original del array, ya que puede ser que nos interese mantenerlo en la forma original. Este era mi caso y por eso la "adapt�".
En la rutina original, ten�a una opci�n para clasificar un archivo... Lo he quitado de este ejemplo, porque no es la parte que interesa. Yo lo utilizaba para el caso de un n�mero grande de datos, ya que la memoria disponible en MS-DOS no era precisamente mucha, sobre todo si el programa ten�a unos Trescientos y pico KB

Bueno, vamos al tema.
En el form de ejemplo he incluido 4 botones para las cuatro formas de clasificar.
Realmente son dos, pero con la variante de poder clasificar directamente el array o usar los punteros al array clasificado.

Tambi�n incluyo un procedimiento para intercambiar valores entre dos variables: SWAP

S�lo voy a incluir el listado de MI rutina, el SWAP y la forma de usarla.
Para ver el ejemplo completo, pulsa en este link (clasif.zip 2.84 KB)

Private Sub Classif(n$(), CL() As Integer, FI As Integer)
    '------------------------------------------------------------
    'Esta rutina est� adaptada de una que "copi�" de un libro
    'para el Amstrad CPC de Data-Becker
    '
    'Los par�metros:
    'n$() es el array a clasificar
    'CL() aqu� se guardan "punteros" a los elementos clasificados
    'FI   es el n�mero de elementos
    '
    'La variable n$() permanece sin clasificar, para acceder a los
    'elementos clasificados habr�a que hacer esto:
    'For i = 0 to FI
    '   Print i, n$(CL(i))
    'Next
    '
    'Puede que sea muy rebuscado, pero lo hice porque mis arrays
    'deber�an permanecer en el mismo orden que estaban originalmente
    '------------------------------------------------------------
    Dim i%, S%, L%, J%, R%, t$

    For i = 1 To FI: CL(i) = i: Next
    If FI < 2 Then Exit Sub             'Nada que clasificar

    ReDim O(30) As Integer, U(30) As Integer
    S = 1
    O(1) = 1
    U(1) = FI

    Do
        L = O(S): R = U(S): S = S - 1
        Do
            i = L: J = R:
            t$ = n$(CL((L + R) / 2))
            If LTrim$(t$) = "" Then t$ = Chr$(255)
            Do
                While (n$(CL(i)) < t$ And i < R): i = i + 1: Wend
                While (n$(CL(J)) > t$ And J > L): J = J - 1: Wend
                If i <= J Then
                    Swap CL(i), CL(J)
                    i = i + 1
                    J = J - 1
                End If
            Loop While i <= J
            If R - i <= J - L Then
                If i < R Then
                    S = S + 1
                    O(S) = i
                    U(S) = R
                End If
                R = J
            Else
                If L < J Then
                    S = S + 1
                    O(S) = L
                    U(S) = J
                End If
                L = i
            End If
        Loop While R > L
    Loop While S > 0
    Erase O, U
End Sub


Private Sub Swap(uno As Variant, dos As Variant)
    'Intercambia dos valores
    Dim tres As Variant

    tres = uno
    uno = dos
    dos = tres
End Sub


Private Sub cmdClassif_Click()
    Dim i As Integer
    Dim t1#, t2#

    MousePointer = vbHourglass

    Label1 = "Un momento..."
    DoEvents

    nItem = List1.ListCount
    ReDim Preserve Nombre(nItem)
    ReDim Orden(0 To nItem) As Integer

    For i = 1 To nItem
        Nombre(i) = List1.List(i - 1)
    Next

    List2.Clear
    t1 = Timer
    Classif Nombre(), Orden(), nItem
    t2 = Timer
    Label1 = "Para " & CStr(nItem) & " elementos= " & Format$(t2 - t1, "###,##0.00") & " seg"
    DoEvents
    For i = 1 To nItem
        List2.AddItem Nombre(Orden(i))
    Next
    MousePointer = vbDefault
End Sub


ir al índice