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