Attribute VB_Name = "bas_k0_sort"
'========================================================================
' Manuel de la Herrán Gascón - mherran@aircenter.net
'========================================================================
Option Explicit
Option Base 1
'-----------------------------------------------------------------------
' k: módulos comunes a más de un proyecto
' Este módulo contiene:
' Funciones de ordenación de arrays
'------------------------------------------------------------------------
' Breve explicación intuitiva de cada método de ordenacion:
'
' BubbleSort
' ==========
' Se intenta colocar el primero en su posición correcta, después el segundo, etc. Para ello:
' Comparar y ordenar el primero con el segundo, el primero con el tercero, ... etc hasta el primero con el último
' con esto conseguimos que el primero de la lista ya este en su posición correcta
' Comparar y ordenar el segundo con el tercero, el segundo con el cuarto, ... etc
' con esto conseguimos que el segundo de la lista ya este en su posición correcta
'
' MergeSort
' =========
' Se divide la lista en dos trozos de igual tamaño (primera mitad y segunda mitad)
' Se ordenan esos dos trozos independientemente mediante MergeSort (recursivo)
' Se combinan esos dos trozos en una nueva lista, cogiendo unas veces de aquí y otras de allá
'
' QuickSort
' =========
' Se elige un valor frontera (no una posición, sino un dato)
' Se crean dos listas, según posean valores mayores o menores que la frontera
' Ahora ya se tiene semiordenada la lista, ya que todos los menores que
' la frontera estan en una parte y los mayores en otra
' Se ordena cada una de esos subconjuntos mediante QuickSort (recursivo)
' Las funciones de QuickSort son una adaptación del código de: (contributed by:)
' Bruno Barreiro Santos brunobs@interbook.net
'
' Notas
' =====
' QuickSort y MergeSort poseen el problema de que para listas muy grandes
' el espacio de memoria dedicado a soportar la recursividad puede no ser suficiente
'
' Pruebas de rendimiento
' ======================
' Estas pruebas se han realizado con ficheros MUY desordenados
' Ordenar fichero de 3.040 lineas
' Cada linea con 20 caracteres aprox.
' QuickSort 1 seg.
' MergeSort 2 seg.
' BubbleSort 1 min. 21 seg.
'
' Ordenar fichero de 61.848 lineas
' Cada linea con 20 caracteres aprox.
' QuickSort 1 min. 49 seg.
' MergeSort 4 min. 52 seg.
' BubbleSort 6 horas aprox.
'------------------------------------------------------------------------
' Notas
' =====
' Al algoritmo de ordenacion, se le paso el dato del grado de desorden
' para que haga nuevas comprobaciones cada cierto tiempo en función
' de ese grado de desorden. Se trata de evitar ordenar algo que ya
' esta ordenado.
'
' Ejemplos del test de ordenacion
' grado_de_desorden es 0..100
' Suponiendo un array de 100 elementos
' que suponen 100 bucles exteriores en burbuja
' grado_de_desorden --> Número de test totales
' 0,1,2             --> 50
' 10                --> 40
' 20                --> 20
' 30                --> 10
' 40                --> 5
' 50                --> 1
' 100               --> 0
' de < a >
'------------------------------------------------------------------------
Sub sortArray1DIntMaxMin(myArray() As Integer)
    Dim grado_de_desorden As Long
    'Compruebo el grado de desorden. Tal vez esté ya ordenado
    grado_de_desorden = gradoDesordenArray1DIntMaxMin(myArray())
    'Lo ordeno
    If grado_de_desorden > 0 Then
        Select Case algoritmo_ordenacion_gcf
            Case CTE_BUBBLESORT
                sortArray1DIntMaxMin_bub myArray(), grado_de_desorden
            Case CTE_QUICKSORT
                sortArray1DIntMaxMin_qui myArray(), LBound(myArray), UBound(myArray)
            Case CTE_MERGESORT
                sortArray1DIntMaxMin_mer myArray(), LBound(myArray), UBound(myArray)
            Case Else
                s_error_ger CTE_ERROR_GRAVE, "Algoritmo de ordenación inexistente"
        End Select
    End If
    'Control de errores
    If control_errores_de_programacion_gcf Then
        If gradoDesordenArray1DIntMaxMin(myArray()) > 0 Then
            s_error_ger CTE_ERROR_GRAVE, "El algoritmo de ordenación no ha ordenado correctamente"
        End If
    End If
End Sub
Sub sortArray1DLngMaxMin(myArray() As Long)
    Dim grado_de_desorden As Long
    'Compruebo el grado de desorden. Tal vez esté ya ordenado
    grado_de_desorden = gradoDesordenArray1DLngMaxMin(myArray())
    'Lo ordeno
    If grado_de_desorden > 0 Then
        Select Case algoritmo_ordenacion_gcf
            Case CTE_BUBBLESORT
                sortArray1DLngMaxMin_bub myArray(), grado_de_desorden
            Case CTE_QUICKSORT
                sortArray1DLngMaxMin_qui myArray(), LBound(myArray), UBound(myArray)
            Case CTE_MERGESORT
                sortArray1DLngMaxMin_mer myArray(), LBound(myArray), UBound(myArray)
            Case Else
                s_error_ger CTE_ERROR_GRAVE, "Algoritmo de ordenación inexistente"
        End Select
    End If
    'Control de errores
    If control_errores_de_programacion_gcf Then
        If gradoDesordenArray1DLngMaxMin(myArray()) > 0 Then
            s_error_ger CTE_ERROR_GRAVE, "El algoritmo de ordenación no ha ordenado correctamente"
        End If
    End If
End Sub
Sub sortArray1DStrMinMax(myArray() As String)
    Dim grado_de_desorden As Long
    'Compruebo el grado de desorden. Tal vez esté ya ordenado
    grado_de_desorden = gradoDesordenArray1DStrMinMax(myArray())
    'Lo ordeno
    If grado_de_desorden > 0 Then
        Select Case algoritmo_ordenacion_gcf
            Case CTE_BUBBLESORT
                sortArray1DStrMinMax_bub myArray(), grado_de_desorden
            Case CTE_QUICKSORT
                sortArray1DStrMinMax_qui myArray(), LBound(myArray), UBound(myArray)
            Case CTE_MERGESORT
                sortArray1DStrMinMax_mer myArray(), LBound(myArray), UBound(myArray)
            Case Else
                s_error_ger CTE_ERROR_GRAVE, "Algoritmo de ordenación inexistente"
        End Select
    End If
    'Control de errores
    If control_errores_de_programacion_gcf Then
        If gradoDesordenArray1DStrMinMax(myArray()) > 0 Then
            s_error_ger CTE_ERROR_GRAVE, "El algoritmo de ordenación no ha ordenado correctamente"
        End If
    End If
End Sub
Sub sort2Array1DLng1DStrMaxMin(myArray1() As Long, myArray2() As String)
'Ordeno ambos arrays según los datos contenidos en el primer array
    Dim grado_de_desorden As Long
    'Compruebo el grado de desorden. Tal vez esté ya ordenado
    grado_de_desorden = gradoDesordenArray1DLngMaxMin(myArray1())
    'Lo ordeno
    If grado_de_desorden > 0 Then
        Select Case algoritmo_ordenacion_gcf
            Case CTE_BUBBLESORT
                sort2Array1DLng1DStrMaxMin_bub myArray1(), myArray2(), grado_de_desorden
            Case CTE_QUICKSORT
                sort2Array1DLng1DStrMaxMin_qui myArray1(), myArray2(), LBound(myArray1), UBound(myArray1)
            Case CTE_MERGESORT
                sort2Array1DLng1DStrMaxMin_mer myArray1(), myArray2(), LBound(myArray1), UBound(myArray1)
            Case Else
                s_error_ger CTE_ERROR_GRAVE, "Algoritmo de ordenación inexistente"
        End Select
    End If
    'Control de errores
    If control_errores_de_programacion_gcf Then
        If gradoDesordenArray1DLngMaxMin(myArray1()) > 0 Then
            s_error_ger CTE_ERROR_GRAVE, "El algoritmo de ordenación no ha ordenado correctamente"
        End If
    End If
End Sub
Sub sort2Array1DStrMinMax(myArray1() As String, myArray2() As String)
'Ordeno ambos arrays según los datos contenidos en el primer array
    Dim grado_de_desorden As Long
    'Compruebo el grado de desorden. Tal vez esté ya ordenado
    grado_de_desorden = gradoDesordenArray1DStrMinMax(myArray1())
    'Lo ordeno
    If grado_de_desorden > 0 Then
        Select Case algoritmo_ordenacion_gcf
            Case CTE_BUBBLESORT
                sort2Array1DStrMinMax_bub myArray1(), myArray2(), grado_de_desorden
            Case CTE_QUICKSORT
                sort2Array1DStrMinMax_qui myArray1(), myArray2(), LBound(myArray1), UBound(myArray1)
            Case CTE_MERGESORT
                sort2Array1DStrMinMax_mer myArray1(), myArray2(), LBound(myArray1), UBound(myArray1)
            Case Else
                s_error_ger CTE_ERROR_GRAVE, "Algoritmo de ordenación inexistente"
        End Select
    End If
    'Control de errores
    If control_errores_de_programacion_gcf Then
        If gradoDesordenArray1DStrMinMax(myArray1()) > 0 Then
            s_error_ger CTE_ERROR_GRAVE, "El algoritmo de ordenación no ha ordenado correctamente"
        End If
    End If
End Sub
Sub sortSum3ArrayOf4Array1DDblMinMax(obj_pintar_p() As Double, obj_pintar_f() As Double, obj_pintar_c() As Double, obj_pintar_o() As Integer)
    Dim grado_de_desorden As Long
    'Compruebo el grado de desorden. Tal vez esté ya ordenado
    grado_de_desorden = gradoDesordenSum3Array1DDblMinMax(obj_pintar_p(), obj_pintar_f(), obj_pintar_c())
    'Lo ordeno
    Select Case algoritmo_ordenacion_gcf
        Case CTE_BUBBLESORT
            sortSum3ArrayOf4Array1DDblMinMax_bub obj_pintar_p(), obj_pintar_f(), obj_pintar_c(), obj_pintar_o(), grado_de_desorden
        Case CTE_QUICKSORT
            sortSum3ArrayOf4Array1DDblMinMax_qui obj_pintar_p(), obj_pintar_f(), obj_pintar_c(), obj_pintar_o(), LBound(obj_pintar_o), UBound(obj_pintar_o)
        Case CTE_MERGESORT
            sortSum3ArrayOf4Array1DDblMinMax_mer obj_pintar_p(), obj_pintar_f(), obj_pintar_c(), obj_pintar_o(), LBound(obj_pintar_o), UBound(obj_pintar_o)
        Case Else
            s_error_ger CTE_ERROR_GRAVE, "Algoritmo de ordenación inexistente"
    End Select
    'Control de errores
    If control_errores_de_programacion_gcf Then
        If gradoDesordenSum3Array1DDblMinMax(obj_pintar_p(), obj_pintar_f(), obj_pintar_c()) > 0 Then
            s_error_ger CTE_ERROR_GRAVE, "El algoritmo de ordenación no ha ordenado correctamente"
        End If
    End If
End Sub
Sub sortSum3ArrayOf4Array1DDblMinMax_bub(obj_pintar_p() As Double, obj_pintar_f() As Double, obj_pintar_c() As Double, obj_pintar_o() As Integer, grado_de_desorden As Long)
    Dim I_n As Long
    Dim I_x As Long
    Dim suma_n As Long
    Dim suma_x As Long
    Dim primero As Long
    Dim ultimo As Long
    Dim temp_p As Double
    Dim temp_f As Double
    Dim temp_c As Double
    Dim temp_o As Long
    ' de < a >
    primero = LBound(obj_pintar_p)
    ultimo = UBound(obj_pintar_p)
    'Comparo cada elemento (todos menos el último)....
    For I_n = primero To ultimo - 1
       'con el siguiente y todos los demás hasta el último
        For I_x = I_n + 1 To ultimo
            suma_n = obj_pintar_p(I_n) + obj_pintar_f(I_n) + obj_pintar_c(I_n)
            suma_x = obj_pintar_p(I_x) + obj_pintar_f(I_x) + obj_pintar_c(I_x)
            If suma_x < suma_n Then
                temp_p = obj_pintar_p(I_x)
                temp_f = obj_pintar_f(I_x)
                temp_c = obj_pintar_c(I_x)
                temp_o = obj_pintar_o(I_x)
                obj_pintar_p(I_x) = obj_pintar_p(I_n)
                obj_pintar_f(I_x) = obj_pintar_f(I_n)
                obj_pintar_c(I_x) = obj_pintar_c(I_n)
                obj_pintar_o(I_x) = obj_pintar_o(I_n)
                obj_pintar_p(I_x) = temp_p
                obj_pintar_f(I_x) = temp_f
                obj_pintar_c(I_x) = temp_c
                obj_pintar_o(I_x) = temp_o
    DoEvents
            End If
        Next I_x
    Next I_n
End Sub
Sub sortSum3ArrayOf4Array1DDblMinMax_mer(obj_pintar_p() As Double, obj_pintar_f() As Double, obj_pintar_c() As Double, obj_pintar_o() As Integer, primero As Long, ultimo As Long)
    s_err_
End Sub
Sub sortSum3ArrayOf4Array1DDblMinMax_qui(obj_pintar_p() As Double, obj_pintar_f() As Double, obj_pintar_c() As Double, obj_pintar_o() As Integer, primero As Long, ultimo As Long)
    s_err_
End Sub
Sub sortArray1DIntMaxMin_bub(myArray() As Integer, grado_de_desorden As Long)
    Dim I_n As Long
    Dim I_x As Long
    Dim primero As Long
    Dim ultimo As Long
    Dim i_temp As Integer
    ' de > a <
    primero = LBound(myArray)
    ultimo = UBound(myArray)
    'Comparo cada elemento (todos menos el último)....
    For I_n = primero To ultimo - 1
       'con el siguiente y todos los demás hasta el último
        For I_x = I_n + 1 To ultimo
            If myArray(I_x) > myArray(I_n) Then
                i_temp = myArray(I_x)
                myArray(I_x) = myArray(I_n)
                myArray(I_n) = i_temp
                DoEvents
            End If
        Next I_x
    Next I_n
End Sub
Sub sortArray1DLngMaxMin_bub(myArray() As Long, grado_de_desorden As Long)
    Dim I_n As Long
    Dim I_x As Long
    Dim primero As Long
    Dim ultimo As Long
    Dim i_temp As Long
    ' de > a <
    primero = LBound(myArray)
    ultimo = UBound(myArray)
    'Comparo cada elemento (todos menos el último)....
    For I_n = primero To ultimo - 1
       'con el siguiente y todos los demás hasta el último
        For I_x = I_n + 1 To ultimo
            If myArray(I_x) > myArray(I_n) Then
                i_temp = myArray(I_x)
                myArray(I_x) = myArray(I_n)
                myArray(I_n) = i_temp
    DoEvents
            End If
        Next I_x
    Next I_n
End Sub
Sub sortArray1DStrMinMax_bub(myArray() As String, grado_de_desorden As Long)
    Dim I_n As Long
    Dim I_x As Long
    Dim primero As Long
    Dim ultimo As Long
    Dim i_temp As String
    primero = LBound(myArray)
    ultimo = UBound(myArray)
    'Comparo cada elemento (todos menos el último)....
    For I_n = primero To ultimo - 1
       'con el siguiente y todos los demás hasta el último
        For I_x = I_n + 1 To ultimo
            If myArray(I_x) < myArray(I_n) Then
                i_temp = myArray(I_x)
                myArray(I_x) = myArray(I_n)
                myArray(I_n) = i_temp
    DoEvents
            End If
        Next I_x
    Next I_n
End Sub
Sub sortArray1DIntMaxMin_qui(myArray() As Integer, primero As Long, ultimo As Long)
'Adaptación del código de Bruno Barreiro Santos brunobs@interbook.net
    Dim i As Long
    Dim last As Long
    Dim temp As Integer
    If primero >= ultimo Then Exit Sub
    'Swap myArray, primero, (primero + ultimo) \ 2
    temp = myArray(primero)
    myArray(primero) = myArray((primero + ultimo) \ 2)
    myArray((primero + ultimo) \ 2) = temp
    last = primero
    i = primero
    Do While i <= ultimo
    If myArray(i) > myArray(primero) Then
        last = last + 1
        'Swap myArray, Last, i
        temp = myArray(last)
        myArray(last) = myArray(i)
        myArray(i) = temp
    End If
    i = i + 1
    Loop
    'Swap myArray, primero, Last
    temp = myArray(primero)
    myArray(primero) = myArray(last)
    myArray(last) = temp
    sortArray1DIntMaxMin_qui myArray, primero, last - 1
    sortArray1DIntMaxMin_qui myArray, last + 1, ultimo
    DoEvents
End Sub
Sub sortArray1DLngMaxMin_qui(myArray() As Long, primero As Long, ultimo As Long)
'Adaptación del código de Bruno Barreiro Santos brunobs@interbook.net
    Dim i As Long
    Dim last As Long
    Dim temp As Long
    If primero >= ultimo Then Exit Sub
    'Swap myArray, primero, (primero + ultimo) \ 2
    temp = myArray(primero)
    myArray(primero) = myArray((primero + ultimo) \ 2)
    myArray((primero + ultimo) \ 2) = temp
    last = primero
    i = primero
    Do While i <= ultimo
    If myArray(i) > myArray(primero) Then
        last = last + 1
        'Swap myArray, Last, i
        temp = myArray(last)
        myArray(last) = myArray(i)
        myArray(i) = temp
    End If
    i = i + 1
    Loop
    'Swap myArray, primero, Last
    temp = myArray(primero)
    myArray(primero) = myArray(last)
    myArray(last) = temp
    sortArray1DLngMaxMin_qui myArray, primero, last - 1
    sortArray1DLngMaxMin_qui myArray, last + 1, ultimo
    DoEvents
End Sub
Sub sort2Array1DStrMinMax_bub(myArray1() As String, myArray2() As String, grado_de_desorden As Long)
    Dim I_n As Long
    Dim I_x As Long
    Dim primero As Long
    Dim ultimo As Long
    Dim temp1 As String
    Dim temp2 As String
    ' de < a >
    primero = LBound(myArray1)
    ultimo = UBound(myArray1)
    'Comparo cada elemento (todos menos el último)....
    For I_n = primero To ultimo - 1
        'con el siguiente y todos los demás hasta el último
        For I_x = I_n + 1 To ultimo
            If myArray1(I_x) > myArray1(I_n) Then
                temp1 = myArray1(I_x)
                temp2 = myArray2(I_x)
                myArray1(I_x) = myArray1(I_n)
                myArray2(I_x) = myArray2(I_n)
                myArray1(I_n) = temp1
                myArray2(I_n) = temp2
                DoEvents
            End If
        Next I_x
    Next I_n
End Sub
Sub sort2Array1DStrMinMax_mer(myArray1() As String, myArray2() As String, primero As Long, ultimo As Long)
    Dim i As Long
    Dim medio As Long
    Dim indice_t As Long
    Dim indice_a As Long
    Dim indice_b As Long
    Dim temp1 As String
    Dim temp2 As String
    Dim arr_temp1() As String
    Dim arr_temp2() As String
    'Un elemento
    If ultimo - primero = 0 Then
        Exit Sub
    End If
    'Dos elementos
    If ultimo - primero = 1 Then
        If myArray1(primero) > myArray1(ultimo) Then
            temp1 = myArray1(primero)
            temp2 = myArray2(primero)
            myArray1(primero) = myArray1(ultimo)
            myArray2(primero) = myArray2(ultimo)
            myArray1(ultimo) = temp1
            myArray2(ultimo) = temp2
            DoEvents
        End If
    Else
        'Tres o mas elementos
        medio = primero + Int((ultimo - primero) / 2)
        sort2Array1DStrMinMax_mer myArray1(), myArray2(), primero, medio
        sort2Array1DStrMinMax_mer myArray1(), myArray2(), medio + 1, ultimo
        'Ahora tengo las dos mitades ordenadas independientemente
        'Copio de forma ordenada a un temporal
        ReDim arr_temp1(primero To ultimo) As String
        ReDim arr_temp2(primero To ultimo) As String
        indice_t = primero
        indice_a = primero
        indice_b = medio + 1
        'Copio hasta que uno quede vacio
        While indice_a <= medio And indice_b <= ultimo
            If myArray1(indice_a) < myArray1(indice_b) Then
                arr_temp1(indice_t) = myArray1(indice_a)
                arr_temp2(indice_t) = myArray2(indice_a)
                indice_t = indice_t + 1
                indice_a = indice_a + 1
            Else
                arr_temp1(indice_t) = myArray1(indice_b)
                arr_temp2(indice_t) = myArray2(indice_b)
                indice_t = indice_t + 1
                indice_b = indice_b + 1
            End If
        Wend
        If indice_t <= ultimo Then
            'Copio todos los que quedan, de uno solo de los dos
            If indice_a > medio Then
                'Quedan de b. Los que quedan estan en la posicion correcta
                'indice_b todavia no lo he tratado
                'Copio del temporal al origen, pero solo la zona en la que trabajo
                'y los que no estan en la zona correcta
                For i = primero To indice_b - 1
                    myArray1(i) = arr_temp1(i)
                    myArray2(i) = arr_temp2(i)
                    DoEvents
                Next i
            Else
                'Quedan de a. Los muevo a temp, al final
                'indice_a todavia no lo he tratado
                'Copio del origen al temporal
                For i = indice_a To medio
                    arr_temp1(indice_t) = myArray1(i)
                    arr_temp2(indice_t) = myArray2(i)
                    indice_t = indice_t + 1
                    DoEvents
                Next i
                'Copio del temporal al origen, pero solo la zona en la que trabajo
                For i = primero To ultimo
                    myArray1(i) = arr_temp1(i)
                    myArray2(i) = arr_temp2(i)
                    DoEvents
                Next i
            End If
        End If
    End If
End Sub
Sub sort2Array1DStrMinMax_qui(myArray1() As String, myArray2() As String, primero As Long, ultimo As Long)
'Ordena dos arrays teniendo en cuenta solo los datos del primer array
'Adaptación del código de Bruno Barreiro Santos brunobs@interbook.net
    Dim i As Long
    Dim last As Long
    Dim temp1 As String
    Dim temp2 As String
    If primero >= ultimo Then Exit Sub
    'Swap myArray, primero, (primero + ultimo) \ 2
    temp1 = myArray1(primero)
    temp2 = myArray2(primero)
    myArray1(primero) = myArray1((primero + ultimo) \ 2)
    myArray2(primero) = myArray2((primero + ultimo) \ 2)
    myArray1((primero + ultimo) \ 2) = temp1
    myArray2((primero + ultimo) \ 2) = temp2
    last = primero
    i = primero
    Do While i <= ultimo
    If myArray1(i) < myArray1(primero) Then
        last = last + 1
        'Swap myArray, Last, i
        temp1 = myArray1(last)
        temp2 = myArray2(last)
        myArray1(last) = myArray1(i)
        myArray2(last) = myArray2(i)
        myArray1(i) = temp1
        myArray2(i) = temp2
    End If
    i = i + 1
    Loop
    'Swap myArray, primero, Last
    temp1 = myArray1(primero)
    temp2 = myArray2(primero)
    myArray1(primero) = myArray1(last)
    myArray2(primero) = myArray2(last)
    myArray1(last) = temp1
    myArray2(last) = temp2
    sort2Array1DStrMinMax_qui myArray1, myArray2, primero, last - 1
    sort2Array1DStrMinMax_qui myArray1, myArray2, last + 1, ultimo
    DoEvents
End Sub
Sub sortArray1DStrMinMax_qui(myArray() As String, primero As Long, ultimo As Long)
'Adaptación del código de Bruno Barreiro Santos brunobs@interbook.net
    Dim i As Long
    Dim last As Long
    Dim temp As String
    If primero >= ultimo Then Exit Sub
    'Swap myArray, primero, (primero + ultimo) \ 2
    temp = myArray(primero)
    myArray(primero) = myArray((primero + ultimo) \ 2)
    myArray((primero + ultimo) \ 2) = temp
    last = primero
    i = primero
    Do While i <= ultimo
    If myArray(i) < myArray(primero) Then
        last = last + 1
        'Swap myArray, Last, i
        temp = myArray(last)
        myArray(last) = myArray(i)
        myArray(i) = temp
    End If
    i = i + 1
    Loop
    'Swap myArray, primero, Last
    temp = myArray(primero)
    myArray(primero) = myArray(last)
    myArray(last) = temp
    sortArray1DStrMinMax_qui myArray, primero, last - 1
    sortArray1DStrMinMax_qui myArray, last + 1, ultimo
    DoEvents
End Sub
Sub sortArray1DIntMaxMin_mer(myArray() As Integer, primero As Long, ultimo As Long)
    Dim i As Long
    Dim medio As Long
    Dim indice_t As Long
    Dim indice_a As Long
    Dim indice_b As Long
    Dim temp As Integer
    Dim arr_temp() As Integer
    'Un elemento
    If ultimo - primero = 0 Then
        Exit Sub
    End If
    'Dos elementos
    If ultimo - primero = 1 Then
        If myArray(primero) < myArray(ultimo) Then
            temp = myArray(primero)
            myArray(primero) = myArray(ultimo)
            myArray(ultimo) = temp
        End If
    Else
        'Tres o mas elementos
        medio = primero + Int((ultimo - primero) / 2)
        sortArray1DIntMaxMin_mer myArray(), primero, medio
        sortArray1DIntMaxMin_mer myArray(), medio + 1, ultimo
        'Ahora tengo las dos mitades ordenadas independientemente
        'Copio de forma ordenada a un temporal
        ReDim arr_temp(primero To ultimo) As Integer
        indice_t = primero
        indice_a = primero
        indice_b = medio + 1
        'Copio hasta que uno quede vacio
        While indice_a <= medio And indice_b <= ultimo
            If myArray(indice_a) > myArray(indice_b) Then
                arr_temp(indice_t) = myArray(indice_a)
                indice_t = indice_t + 1
                indice_a = indice_a + 1
            Else
                arr_temp(indice_t) = myArray(indice_b)
                indice_t = indice_t + 1
                indice_b = indice_b + 1
            End If
        Wend
        If indice_t <= ultimo Then
            'Copio todos los que quedan, de uno solo de los dos
            If indice_a > medio Then
                'Quedan de b. Los que quedan estan en la posicion correcta
                'indice_b todavia no lo he tratado
                'Copio del temporal al origen, pero solo la zona en la que trabajo
                'y los que no estan en la zona correcta
                For i = primero To indice_b - 1
                    myArray(i) = arr_temp(i)
                    DoEvents
                Next i
            Else
                'Quedan de a. Los muevo a temp, al final
                'indice_a todavia no lo he tratado
                'Copio del origen al temporal
                For i = indice_a To medio
                    arr_temp(indice_t) = myArray(i)
                    indice_t = indice_t + 1
                    DoEvents
                Next i
                'Copio del temporal al origen, pero solo la zona en la que trabajo
                For i = primero To ultimo
                    myArray(i) = arr_temp(i)
                    DoEvents
                Next i
            End If
        End If
    End If
End Sub
Sub sortArray1DLngMaxMin_mer(myArray() As Long, primero As Long, ultimo As Long)
    Dim i As Long
    Dim medio As Long
    Dim indice_t As Long
    Dim indice_a As Long
    Dim indice_b As Long
    Dim temp As Long
    Dim arr_temp() As Long
    'Un elemento
    If ultimo - primero = 0 Then
        Exit Sub
    End If
    'Dos elementos
    If ultimo - primero = 1 Then
        If myArray(primero) < myArray(ultimo) Then
            temp = myArray(primero)
            myArray(primero) = myArray(ultimo)
            myArray(ultimo) = temp
        End If
    Else
        'Tres o mas elementos
        medio = primero + Int((ultimo - primero) / 2)
        sortArray1DLngMaxMin_mer myArray(), primero, medio
        sortArray1DLngMaxMin_mer myArray(), medio + 1, ultimo
        'Ahora tengo las dos mitades ordenadas independientemente
        'Copio de forma ordenada a un temporal
        ReDim arr_temp(primero To ultimo) As Long
        indice_t = primero
        indice_a = primero
        indice_b = medio + 1
        'Copio hasta que uno quede vacio
        While indice_a <= medio And indice_b <= ultimo
            If myArray(indice_a) > myArray(indice_b) Then
                arr_temp(indice_t) = myArray(indice_a)
                indice_t = indice_t + 1
                indice_a = indice_a + 1
            Else
                arr_temp(indice_t) = myArray(indice_b)
                indice_t = indice_t + 1
                indice_b = indice_b + 1
            End If
        Wend
        If indice_t <= ultimo Then
            'Copio todos los que quedan, de uno solo de los dos
            If indice_a > medio Then
                'Quedan de b. Los que quedan estan en la posicion correcta
                'indice_b todavia no lo he tratado
                'Copio del temporal al origen, pero solo la zona en la que trabajo
                'y los que no estan en la zona correcta
                For i = primero To indice_b - 1
                    myArray(i) = arr_temp(i)
                    DoEvents
                Next i
            Else
                'Quedan de a. Los muevo a temp, al final
                'indice_a todavia no lo he tratado
                'Copio del origen al temporal
                For i = indice_a To medio
                    arr_temp(indice_t) = myArray(i)
                    indice_t = indice_t + 1
                    DoEvents
                Next i
                'Copio del temporal al origen, pero solo la zona en la que trabajo
                For i = primero To ultimo
                    myArray(i) = arr_temp(i)
                    DoEvents
                Next i
            End If
        End If
    End If
End Sub
Sub sortArray1DStrMinMax_mer(myArray() As String, primero As Long, ultimo As Long)
    Dim i As Long
    Dim medio As Long
    Dim indice_t As Long
    Dim indice_a As Long
    Dim indice_b As Long
    Dim temp As String
    Dim arr_temp() As String
    'Un elemento
    If ultimo - primero = 0 Then
        Exit Sub
    End If
    'Dos elementos
    If ultimo - primero = 1 Then
        If myArray(primero) > myArray(ultimo) Then
            temp = myArray(primero)
            myArray(primero) = myArray(ultimo)
            myArray(ultimo) = temp
        End If
    Else
        'Tres o mas elementos
        medio = primero + Int((ultimo - primero) / 2)
        sortArray1DStrMinMax_mer myArray(), primero, medio
        sortArray1DStrMinMax_mer myArray(), medio + 1, ultimo
        'Ahora tengo las dos mitades ordenadas independientemente
        'Copio de forma ordenada a un temporal
        ReDim arr_temp(primero To ultimo) As String
        indice_t = primero
        indice_a = primero
        indice_b = medio + 1
        'Copio hasta que uno quede vacio
        While indice_a <= medio And indice_b <= ultimo
            If myArray(indice_a) < myArray(indice_b) Then
                arr_temp(indice_t) = myArray(indice_a)
                indice_t = indice_t + 1
                indice_a = indice_a + 1
            Else
                arr_temp(indice_t) = myArray(indice_b)
                indice_t = indice_t + 1
                indice_b = indice_b + 1
            End If
        Wend
        If indice_t <= ultimo Then
            'Copio todos los que quedan, de uno solo de los dos
            If indice_a > medio Then
                'Quedan de b. Los que quedan estan en la posicion correcta
                'indice_b todavia no lo he tratado
                'Copio del temporal al origen, pero solo la zona en la que trabajo
                'y los que no estan en la zona correcta
                For i = primero To indice_b - 1
                    myArray(i) = arr_temp(i)
                    DoEvents
                Next i
            Else
                'Quedan de a. Los muevo a temp, al final
                'indice_a todavia no lo he tratado
                'Copio del origen al temporal
                For i = indice_a To medio
                    arr_temp(indice_t) = myArray(i)
                    indice_t = indice_t + 1
                    DoEvents
                Next i
                'Copio del temporal al origen, pero solo la zona en la que trabajo
                For i = primero To ultimo
                    myArray(i) = arr_temp(i)
                    DoEvents
                Next i
            End If
        End If
    End If
End Sub
Sub sort2Array1DLng1DStrMaxMin_bub(myArray1() As Long, myArray2() As String, grado_de_desorden As Long)
    Dim I_n As Long
    Dim I_x As Long
    Dim primero As Long
    Dim ultimo As Long
    Dim temp1 As Long
    Dim temp2 As String
    ' de > a <
    primero = LBound(myArray1)
    ultimo = UBound(myArray1)
    'Comparo cada elemento (todos menos el último)....
    For I_n = primero To ultimo - 1
        'con el siguiente y todos los demás hasta el último
        For I_x = I_n + 1 To ultimo
            If myArray1(I_x) < myArray1(I_n) Then
                temp1 = myArray1(I_x)
                temp2 = myArray2(I_x)
                myArray1(I_x) = myArray1(I_n)
                myArray2(I_x) = myArray2(I_n)
                myArray1(I_n) = temp1
                myArray2(I_n) = temp2
                DoEvents
            End If
        Next I_x
    Next I_n
End Sub
Sub sort2Array1DLng1DStrMaxMin_mer(myArray1() As Long, myArray2() As String, primero As Long, ultimo As Long)
    Dim i As Long
    Dim medio As Long
    Dim indice_t As Long
    Dim indice_a As Long
    Dim indice_b As Long
    Dim temp1 As Long
    Dim temp2 As String
    Dim arr_temp1() As Long
    Dim arr_temp2() As String
    'Un elemento
    If ultimo - primero = 0 Then
        Exit Sub
    End If
    'Dos elementos
    If ultimo - primero = 1 Then
        If myArray1(primero) < myArray1(ultimo) Then
            temp1 = myArray1(primero)
            temp2 = myArray2(primero)
            myArray1(primero) = myArray1(ultimo)
            myArray2(primero) = myArray2(ultimo)
            myArray1(ultimo) = temp1
            myArray2(ultimo) = temp2
            DoEvents
        End If
    Else
        'Tres o mas elementos
        medio = primero + Int((ultimo - primero) / 2)
        sort2Array1DLng1DStrMaxMin_mer myArray1(), myArray2(), primero, medio
        sort2Array1DLng1DStrMaxMin_mer myArray1(), myArray2(), medio + 1, ultimo
        'Ahora tengo las dos mitades ordenadas independientemente
        'Copio de forma ordenada a un temporal
        ReDim arr_temp1(primero To ultimo) As Long
        ReDim arr_temp2(primero To ultimo) As String
        indice_t = primero
        indice_a = primero
        indice_b = medio + 1
        'Copio hasta que uno quede vacio
        While indice_a <= medio And indice_b <= ultimo
            If myArray1(indice_a) < myArray1(indice_b) Then
                arr_temp1(indice_t) = myArray1(indice_a)
                arr_temp2(indice_t) = myArray2(indice_a)
                indice_t = indice_t + 1
                indice_a = indice_a + 1
            Else
                arr_temp1(indice_t) = myArray1(indice_b)
                arr_temp2(indice_t) = myArray2(indice_b)
                indice_t = indice_t + 1
                indice_b = indice_b + 1
            End If
        Wend
        If indice_t <= ultimo Then
            'Copio todos los que quedan, de uno solo de los dos
            If indice_a < medio Then
                'Quedan de b. Los que quedan estan en la posicion correcta
                'indice_b todavia no lo he tratado
                'Copio del temporal al origen, pero solo la zona en la que trabajo
                'y los que no estan en la zona correcta
                For i = primero To indice_b - 1
                    myArray1(i) = arr_temp1(i)
                    myArray2(i) = arr_temp2(i)
                    DoEvents
                Next i
            Else
                'Quedan de a. Los muevo a temp, al final
                'indice_a todavia no lo he tratado
                'Copio del origen al temporal
                For i = indice_a To medio
                    arr_temp1(indice_t) = myArray1(i)
                    arr_temp2(indice_t) = myArray2(i)
                    indice_t = indice_t + 1
                    DoEvents
                Next i
                'Copio del temporal al origen, pero solo la zona en la que trabajo
                For i = primero To ultimo
                    myArray1(i) = arr_temp1(i)
                    myArray2(i) = arr_temp2(i)
                    DoEvents
                Next i
            End If
        End If
    End If
End Sub
Sub sort2Array1DLng1DStrMaxMin_qui(myArray1() As Long, myArray2() As String, primero As Long, ultimo As Long)
'Ordena dos arrays teniendo en cuenta solo los datos del primer array
'Adaptación del código de Bruno Barreiro Santos brunobs@interbook.net
    Dim i As Long
    Dim last As Long
    Dim temp1 As Long
    Dim temp2 As String
    If primero >= ultimo Then Exit Sub
    'Swap myArray, primero, (primero + ultimo) \ 2
    temp1 = myArray1(primero)
    temp2 = myArray2(primero)
    myArray1(primero) = myArray1((primero + ultimo) \ 2)
    myArray2(primero) = myArray2((primero + ultimo) \ 2)
    myArray1((primero + ultimo) \ 2) = temp1
    myArray2((primero + ultimo) \ 2) = temp2
    last = primero
    i = primero
    Do While i <= ultimo
    If myArray1(i) < myArray1(primero) Then
        last = last + 1
        'Swap myArray, Last, i
        temp1 = myArray1(last)
        temp2 = myArray2(last)
        myArray1(last) = myArray1(i)
        myArray2(last) = myArray2(i)
        myArray1(i) = temp1
        myArray2(i) = temp2
    End If
    i = i + 1
    Loop
    'Swap myArray, primero, Last
    temp1 = myArray1(primero)
    temp2 = myArray2(primero)
    myArray1(primero) = myArray1(last)
    myArray2(primero) = myArray2(last)
    myArray1(last) = temp1
    myArray2(last) = temp2
    sort2Array1DLng1DStrMaxMin_qui myArray1, myArray2, primero, last - 1
    sort2Array1DLng1DStrMaxMin_qui myArray1, myArray2, last + 1, ultimo
    DoEvents
End Sub
Sub unsortArray_Int(myArray() As Integer)
'Desordena el array completo
'myArray() es un parametro de entrada-salida
    Dim i As Long
    Dim primero As Long
    Dim ultimo As Long
    Dim longitud As Long
    Dim temp As Integer
    Dim uno As Integer
    Dim otro As Integer
    primero = LBound(myArray)
    ultimo = UBound(myArray)
    longitud = ultimo - primero + 1
    For i = 1 To 2 * longitud
       'Intercambio 2 elementos a azar
        uno = randDistDiscUnifLbUb1_l(primero, ultimo)
        otro = randDistDiscUnifLbUb1_l(primero, ultimo)
        temp = myArray(uno)
        myArray(uno) = myArray(otro)
        myArray(otro) = temp
    Next i
End Sub
Sub unsortArray_lng(myArray() As Long)
'Desordena el array completo
'myArray() es un parametro de entrada-salida
    Dim i As Long
    Dim primero As Long
    Dim ultimo As Long
    Dim longitud As Long
    Dim temp As Long
    Dim uno As Long
    Dim otro As Long
    primero = LBound(myArray)
    ultimo = UBound(myArray)
    longitud = ultimo - primero + 1
    For i = 1 To 2 * longitud
       'Intercambio 2 elementos a azar
        uno = randDistDiscUnifLbUb1_l(primero, ultimo)
        otro = randDistDiscUnifLbUb1_l(primero, ultimo)
        temp = myArray(uno)
        myArray(uno) = myArray(otro)
        myArray(otro) = temp
    Next i
End Sub
Sub unsortArray_str(myArray() As String)
'Desordena el array completo
'myArray() es un parametro de entrada-salida
    
    Dim i As Long
    Dim primero As Long
    Dim ultimo As Long
    Dim longitud As Long
    Dim temp As String
    Dim uno As String
    Dim otro As String
    primero = LBound(myArray)
    ultimo = UBound(myArray)
    longitud = ultimo - primero + 1
    For i = 1 To 2 * longitud
       'Intercambio 2 elementos a azar
        uno = randDistDiscUnifLbUb1_l(primero, ultimo)
        otro = randDistDiscUnifLbUb1_l(primero, ultimo)
        temp = myArray(uno)
        myArray(uno) = myArray(otro)
        myArray(otro) = temp
    Next i
End Sub
Function gradoDesordenArray1DStrMinMax(myArray() As String) As Integer
'Devuelve el grado de desorden.
'O   = ordenado
'100 = maximo grado de desorden
    Dim grado_de_desorden As Long
    Dim i As Long
    grado_de_desorden = 0
    For i = LBound(myArray) To UBound(myArray) - 1
        If myArray(i) > myArray(i + 1) Then
            grado_de_desorden = grado_de_desorden + 1
        End If
    Next i
    'Añado siempre 1 por si tiene decimales (por si por ser muy pequeño el desorden sale menor que uno)
    If grado_de_desorden > 0 Then
        grado_de_desorden = Int(100 * grado_de_desorden / (UBound(myArray) - LBound(myArray) + 1))
        grado_de_desorden = grado_de_desorden + 1
    End If
    gradoDesordenArray1DStrMinMax = grado_de_desorden
End Function
Function gradoDesordenArray1DStrMaxMin(myArray() As String) As Integer
'Devuelve el grado de desorden.
'O   = ordenado
'100 = maximo grado de desorden
    Dim grado_de_desorden As Long
    Dim i As Long
    grado_de_desorden = 0
    For i = LBound(myArray) To UBound(myArray) - 1
        If myArray(i) < myArray(i + 1) Then
            grado_de_desorden = grado_de_desorden + 1
        End If
    Next i
    'Añado siempre 1 por si tiene decimales
    If grado_de_desorden > 0 Then
        grado_de_desorden = grado_de_desorden + 1
    End If
    grado_de_desorden = Int(100 * grado_de_desorden / (UBound(myArray) - LBound(myArray) + 1))
    gradoDesordenArray1DStrMaxMin = grado_de_desorden
End Function
Function gradoDesordenArray1DDblMaxMin(myArray() As Double) As Integer
'Devuelve el grado de desorden.
'O   = ordenado
'100 = maximo grado de desorden
'Los grados de desorden determinados por esta funcion son altamente subjetivos
'como se observa ;-)
    Dim grado_de_desorden As Long
    Dim i As Long
    grado_de_desorden = 0
    For i = LBound(myArray) To UBound(myArray) - 1
        If myArray(i) < myArray(i + 1) Then
            grado_de_desorden = grado_de_desorden + 1
        End If
    Next i
    'Añado siempre 1 por si tiene decimales (por si por ser muy pequeño el desorden sale menor que uno)
    If grado_de_desorden > 0 Then
        grado_de_desorden = Int(100 * grado_de_desorden / (UBound(myArray) - LBound(myArray) + 1))
        grado_de_desorden = grado_de_desorden + 1
    End If
    gradoDesordenArray1DDblMaxMin = grado_de_desorden
End Function
Function gradoDesordenArray1DIntMaxMin(myArray() As Integer) As Integer
'Devuelve el grado de desorden.
'O   = ordenado
'100 = maximo grado de desorden
'Los grados de desorden determinados por esta funcion son altamente subjetivos
'como se observa ;-)
    Dim grado_de_desorden As Long
    Dim i As Long
    grado_de_desorden = 0
    For i = LBound(myArray) To UBound(myArray) - 1
        If myArray(i) < myArray(i + 1) Then
            grado_de_desorden = grado_de_desorden + 1
        End If
    Next i
    'Añado siempre 1 por si tiene decimales (por si por ser muy pequeño el desorden sale menor que uno)
    If grado_de_desorden > 0 Then
        grado_de_desorden = Int(100 * grado_de_desorden / (UBound(myArray) - LBound(myArray) + 1))
        grado_de_desorden = grado_de_desorden + 1
    End If
    gradoDesordenArray1DIntMaxMin = grado_de_desorden
End Function
Function gradoDesordenArray1DLngMaxMin(myArray() As Long) As Integer
'Devuelve el grado de desorden.
'O   = ordenado
'100 = maximo grado de desorden
'Los grados de desorden determinados por esta funcion son altamente subjetivos
'como se observa ;-)
    Dim grado_de_desorden As Long
    Dim i As Long
    grado_de_desorden = 0
    For i = LBound(myArray) To UBound(myArray) - 1
        If myArray(i) < myArray(i + 1) Then
            grado_de_desorden = grado_de_desorden + 1
        End If
    Next i
    'Añado siempre 1 por si tiene decimales (por si por ser muy pequeño el desorden sale menor que uno)
    If grado_de_desorden > 0 Then
        grado_de_desorden = Int(100 * grado_de_desorden / (UBound(myArray) - LBound(myArray) + 1))
        grado_de_desorden = grado_de_desorden + 1
    End If
    gradoDesordenArray1DLngMaxMin = grado_de_desorden
End Function
Function gradoDesordenSum3Array1DDblMinMax(myArray1() As Double, myArray2() As Double, myArray3() As Double) As Integer
    s_err_
End Function
Sub sortArray2DStrWithArray1DStrMaxMin(myArray_datos() As String, myArray_claves() As String)
'=================================================================
'Ordena un array de 2 dimensiones de tipo string (datos)
'por la segunda de sus dimensiones
'según la información contenida en un array de 1 dimensión de tipo double (claves)
'que tambien se ordena
'El número de registros de claves debe ser igual al numero de
'valores de la segunda dimension del array de datos
'=================================================================
'Por ejemplo, los arrays contienen
'datos(1 to numero_de_genes_por_agente, 1 to numero_de_agentes)
'claves(1 to numero_de_agentes)
'y se trata de ordenar los datos por la segunda dimension (agentes)
'y las claves (agentes) según los pesos
'=================================================================
    
    Dim grado_de_desorden As Long
    'Compruebo el grado de desorden. Tal vez esté ya ordenado
    grado_de_desorden = gradoDesordenArray1DStrMaxMin(myArray_claves())
    'Lo ordeno
    Select Case algoritmo_ordenacion_gcf
        Case CTE_BUBBLESORT
            sortArray2DStrWithArray1DStrMaxMin_bub myArray_datos(), myArray_claves(), grado_de_desorden
        Case CTE_QUICKSORT
            sortArray2DStrWithArray1DStrMaxMin_qui myArray_datos(), myArray_claves(), LBound(myArray_claves), UBound(myArray_claves)
        Case CTE_MERGESORT
            sortArray2DStrWithArray1DStrMaxMin_mer myArray_datos(), myArray_claves(), LBound(myArray_claves), UBound(myArray_claves)
        Case Else
            s_error_ger CTE_ERROR_GRAVE, "Algoritmo de ordenación inexistente"
    End Select
    'Control de errores
    If control_errores_de_programacion_gcf Then
        If gradoDesordenArray1DStrMaxMin(myArray_claves()) > 0 Then
            s_error_ger CTE_ERROR_GRAVE, "El algoritmo de ordenación no ha ordenado correctamente"
        End If
    End If
End Sub
Sub sortArray2DStrWithArray1DStrMaxMin_bub(myArray_datos() As String, myArray_claves() As String, grado_de_desorden As Long)
    Dim I_n As Integer
    Dim I_x As Integer
    Dim cont_g As Integer
    Dim primero As Integer
    Dim ultimo As Integer
    Dim s_temp As String
    ' de > a <
    primero = 1
    ultimo = UBound(myArray_claves) 'numero de agentes
    'Comparo cada elemento (todos menos el último)....
    For I_n = primero To ultimo - 1
       'con el siguiente y todos los demás hasta el último
        For I_x = I_n + 1 To ultimo
            If myArray_claves(I_x) > myArray_claves(I_n) Then
                'Cambio todos sus elementos (datos de ese agente)
                For cont_g = 1 To UBound(myArray_datos, 1)
                    s_temp = myArray_datos(cont_g, I_x)
                    myArray_datos(cont_g, I_x) = myArray_datos(cont_g, I_n)
                    myArray_datos(cont_g, I_n) = s_temp
                Next cont_g
                'Cambio su clave (peso)
                s_temp = myArray_claves(I_x)
                myArray_claves(I_x) = myArray_claves(I_n)
                myArray_claves(I_n) = s_temp
            End If
DoEvents
        Next I_x
    Next I_n
End Sub
Sub sortArray2DStrWithArray1DStrMaxMin_qui(myArray_datos() As String, myArray_claves() As String, primero As Long, ultimo As Long)
'Adaptación del código de Bruno Barreiro Santos brunobs@interbook.net
    Dim cont_g As Long
    Dim i As Long
    Dim last As Long
    Dim s_temp As String
    If primero >= ultimo Then Exit Sub
    '--------------------------------------------------------------------
    'Swap myArray, primero, (primero + ultimo) \ 2
    'Cambio todos sus elementos (datos de ese agente)
    For cont_g = 1 To UBound(myArray_datos, 1)
        s_temp = myArray_datos(cont_g, primero)
        myArray_datos(cont_g, primero) = myArray_datos(cont_g, (primero + ultimo) \ 2)
        myArray_datos(cont_g, (primero + ultimo) \ 2) = s_temp
    Next cont_g
    'Cambio su clave (peso)
    s_temp = myArray_claves(primero)
    myArray_claves(primero) = myArray_claves((primero + ultimo) \ 2)
    myArray_claves((primero + ultimo) \ 2) = s_temp
    '--------------------------------------------------------------------
    last = primero
    i = primero
    Do While i <= ultimo
    If myArray_claves(i) > myArray_claves(primero) Then
        last = last + 1
        '--------------------------------------------------------------------
        'Swap myArray, Last, i
        'Cambio todos sus elementos (datos de ese agente)
        For cont_g = 1 To UBound(myArray_datos, 1)
            s_temp = myArray_datos(cont_g, last)
            myArray_datos(cont_g, last) = myArray_datos(cont_g, i)
            myArray_datos(cont_g, i) = s_temp
        Next cont_g
        'Cambio su clave (peso)
        s_temp = myArray_claves(last)
        myArray_claves(last) = myArray_claves(i)
        myArray_claves(i) = s_temp
        '--------------------------------------------------------------------
    End If
    i = i + 1
    Loop
    '--------------------------------------------------------------------
    'Swap myArray, primero, Last
    'Cambio todos sus elementos (datos de ese agente)
    For cont_g = 1 To UBound(myArray_datos, 1)
        s_temp = myArray_datos(cont_g, primero)
        myArray_datos(cont_g, primero) = myArray_datos(cont_g, last)
        myArray_datos(cont_g, last) = s_temp
    Next cont_g
    'Cambio su clave (peso)
    s_temp = myArray_claves(primero)
    myArray_claves(primero) = myArray_claves(last)
    myArray_claves(last) = s_temp
    '--------------------------------------------------------------------
    sortArray2DStrWithArray1DStrMaxMin_qui myArray_datos(), myArray_claves(), primero, last - 1
    sortArray2DStrWithArray1DStrMaxMin_qui myArray_datos(), myArray_claves(), last + 1, ultimo
    DoEvents
End Sub
Sub sortArray2DStrWithArray1DStrMaxMin_mer(myArray_datos() As String, myArray_claves() As String, primero As Long, ultimo As Long)
    s_error_ger CTE_ERROR_GRAVE, "Merge Sort no programado"
End Sub
Sub S_OrdenarEspecialInt(ArrayGuia() As Integer, ArrayAOrdenar() As Integer)
    '=======================================================
    'Ordena un array en funcion de los valores de otro array
    '=======================================================
    'Esta función toma un array, realiza una copia, y
    'ordena otro array (machacando la copia, pq la ordena)
    Dim I_n As Integer
    Dim I_x As Integer
    Dim primero As Long
    Dim ultimo As Long
    Dim i_temp As Integer
    Dim Copia() As Integer
    s_copiar_array1int ArrayGuia(), Copia()
    ' de > a <
    primero = LBound(Copia)
    ultimo = UBound(Copia)
    'Comparo cada elemento (todos menos el último)....
    For I_n = primero To ultimo - 1
       'con el siguiente y todos los demás hasta el último
        For I_x = I_n + 1 To ultimo
    DoEvents
            If Copia(I_x) > Copia(I_n) Then
               'en este orden
               'ordeno el array de patrones
                i_temp = Copia(I_x)
                Copia(I_x) = Copia(I_n)
                Copia(I_n) = i_temp
    
               'ordeno los indices
                i_temp = ArrayAOrdenar(I_x)
                ArrayAOrdenar(I_x) = ArrayAOrdenar(I_n)
                ArrayAOrdenar(I_n) = i_temp
    
    
            End If
        Next I_x
    Next I_n
End Sub
Function Fi_OrdenarEspecial2(ArrayGuia() As Integer, ArrayAOrdenar() As Integer, primero As Integer, ultimo As Integer)
'Esta función toma un array, realiza una copia, y
'ordena otro array (machacando la copia, pq la ordena)
'y lo hace entre 2 límites que se le dan como parámetros
    Dim I_n As Integer
    Dim I_x As Integer
    Dim i_temp As Integer
    Dim Copia() As Integer
    s_copiar_array1int ArrayGuia(), Copia()
    ' de > a <
    'Comparo cada elemento (todos menos el último)....
    For I_n = primero To ultimo - 1
       'con el siguiente y todos los demás hasta el último
        For I_x = I_n + 1 To ultimo
    DoEvents
            If Copia(I_x) > Copia(I_n) Then
               'en este orden
               'ordeno el array de patrones
                i_temp = Copia(I_x)
                Copia(I_x) = Copia(I_n)
                Copia(I_n) = i_temp
    
               'ordeno los indices
                i_temp = ArrayAOrdenar(I_x)
                ArrayAOrdenar(I_x) = ArrayAOrdenar(I_n)
                ArrayAOrdenar(I_n) = i_temp
            End If
        Next I_x
    Next I_n
End Function
Sub Si_DesordenMedioArray_2D_S(myArray() As String, maximo_dim1 As Integer, primero As Long, ultimo As Long)

'Desordena el segmento de un array que va desde
'primero hasta ultimo

Dim i As Long
Dim longitud As Long
ReDim temp(1 To maximo_dim1) As String
Dim uno As String
Dim otro As String
Dim j As Long

longitud = ultimo - primero + 1
For i = 1 To 2 * longitud
   'Intercambio 2 elementos a azar
    uno = randDistDiscUnifLbUb1_l(primero, ultimo)
    otro = randDistDiscUnifLbUb1_l(primero, ultimo)
   'Muevo cada elemento de la primera dimensión, que son estaticos
    For j = 1 To maximo_dim1
        temp(j) = myArray(j, uno)
        myArray(j, uno) = myArray(j, otro)
        myArray(j, otro) = temp(j)
    Next j
Next i

End Sub
Sub Si_DesordenMedioArrayI(myArray() As Integer, primero As Long, ultimo As Long)
'Desordena el segmento de un array que va desde
'primero hasta ultimo
    Dim i As Integer
    Dim longitud As Long
    Dim temp As Integer
    Dim uno As Integer
    Dim otro As Integer
    longitud = ultimo - primero + 1
    For i = 1 To 2 * longitud
       'Intercambio 2 elementos a azar
        uno = randDistDiscUnifLbUb1_l(primero, ultimo)
        otro = randDistDiscUnifLbUb1_l(primero, ultimo)
        temp = myArray(uno)
        myArray(uno) = myArray(otro)
        myArray(otro) = temp
    Next i
End Sub
