Está en la página 1de 8

UNIVERSIDAD NACIONAL DE SAN ANTONIO ABAD DEL

CUSCO
FACULTAD DE INGENIERÍA ELÉCTRICA, ELECTRÓNICA, INFORMÁTICA Y
MECÁNICA
ESCUELA PROFESIONAL DE INGENIERÍA INFORMÁTICA Y DE SISTEMAS

INFORME: ALGORITMO DE QUICKSORT

Curso:
Análisis y Diseño de algoritmos

Docente:
María del Pilar Veneras Vergara

Estudiante:
Escobedo Mescco, Angie

CUSCO-PERU
2021
UNIVERSIDAD NACIONAL SAN ANTONIO ABAD DEL CUSCO
FACULTAD DE INGENIERÍA ELÉCTRICA, ELECTRÓNICA, INFORMÁTICA Y MECÁNICA
ESCUELA PROFESIONAL DE INGENIERÍA INFORMATICA Y DE SISTEMAS

CAPITULO 1: QUICKSORT
Quicksort es un algoritmo de clasificación cuyo tiempo de ejecución en el peor de los
casos es Θ (n 2) en una matriz de entrada de n números. A pesar de este lento tiempo de
ejecución en el peor de los casos, la ordenación rápida es a menudo la mejor opción
práctica para la clasificación porque es notablemente eficiente en promedio: su tiempo
de ejecución esperado es Θ(nlg(n)) y los factores constantes ocultos en Θ(nlg(n)) la
notación es bastante pequeña.

DEFINICIÓN DEL ALGORITMO

La ordenación rápida, como la ordenación por fusión, se basa en el paradigma de divide


y vencerás. Aquí está el proceso de dividir y conquistar en tres pasos para clasificar un
subarreglo A típico [p……… r].

Dividir: La matriz A [p……. r] se divide (reordena) en dos subarreglos no


vacíos A [ p……q] y A [ q + 1 …. r] tal que cada elemento de A [ p…. q] es menor o
igual que cada elemento de A [ q + 1 … r]. El índice q se calcula como parte de este
procedimiento de partición.

Conquistar: Los dos subarreglos A [ p… q] y A [ q + 1 …. r] se ordenan mediante


llamadas recursivas a Quicksort.

Combinar: dado que los subarreglos se ordenan en su lugar, no es necesario trabajar


para combinarlos: el arreglo completo A [ p… r] ahora está ordenado.

El siguiente procedimiento implementa la ordenación rápida.

QUICKSORT ( A, p, r )
1 si p < r
2 luego q PARTICIÓN ( A, p, r )
3 QUICKSORT ( A, p, q )
4 QUICKSORT ( A, q + 1, r )

Para ordenar una un arreglo A, la llamada inicial es QUICKSORT ( A , 0, longitud [ A ]-1).

ALGORITMO(Pseudocódigo)
QUICK_SORT ( A )
QUICKSORT ( A, 0, len(A) - 1)

QUICKSORT ( A, p, r )
1 si p < r
2 luego q PARTICIÓN ( A, p, r )
3 QUICKSORT ( A, p, q )
4 QUICKSORT ( A, q + 1, r )

PARTICION ( A, p, r)
1 pivot ← A[p]
2 i ← p + 1
3 j ← r
UNIVERSIDAD NACIONAL SAN ANTONIO ABAD DEL CUSCO
FACULTAD DE INGENIERÍA ELÉCTRICA, ELECTRÓNICA, INFORMÁTICA Y MECÁNICA
ESCUELA PROFESIONAL DE INGENIERÍA INFORMATICA Y DE SISTEMAS

4 terminado ← false
5 mientras es verdadero
6 mientras i <= j and A[i] <= pivot
7 i ← i + 1
8 mientras j >= i and A[j] >= pivot
9 j ← j – 1
10 si j < i
11 terminado ← verdad
12 caso contrario
13 intercambiar A[i] ↔ A[j]
14 intercambiar A[p] ↔ A[j]
15 regresa j

El ejemplo siguiente muestra cómo funciona la PARTICIÓN . Primero selecciona un


elemento x = A [ p ] de A [ p… r ] como un elemento "pivote inicial" alrededor del cual
dividir A [ p… r ]. Luego crece dos regiones A [ p…i ] y A [ j…r ] de la parte superior
e inferior de A [ p… r ], respectivamente, de modo que cada elemento de A [ p… i ] es
menor o igual que x y todos los elementos de A [ j… r] es mayor o igual a
x . Inicialmente, i = p - 1 y j = r, por lo que las dos regiones están vacías.

Dentro del cuerpo de la mientras bucle, el índice j se decrementa y el índice i se


incrementa, en las líneas 6-7, hasta A [ i ] x A [ j ]. Suponiendo que estas
desigualdades son estrictas, A [ i ] es demasiado grande para pertenecer a la región
inferior y A [ j ] es demasiado pequeña para pertenecer a la región superior. Así,
intercambiando A [ i ] y A [ j ] como se hace en la línea 10, podemos extender las dos
regiones. (Si las desigualdades no son estrictas, el intercambio se puede realizar de
todos modos).

El cuerpo de los mientras repite el bucle hasta i j , en cuyo momento todo el


array A [ p… r ] se ha dividido en dos subarreglos A [ p… q ] y A [ q + 1… r ],
donde p q < r , tal que ningún elemento de A [ p… q ] es más grande que cualquier
elemento de A [ q + 1…r ]. El valor q = j se devuelve al final del procedimiento.

Conceptualmente, el procedimiento de partición realiza una función simple: coloca


elementos menores que x en la región izquierda de la matriz y elementos mayores
que x en la región derecha. Sin embargo, hay tecnicismos que hacen que el
pseudocódigo de PARTICIÓN sea un poco complicado. Por ejemplo, los
índices i y j nunca indexan el subarreglo A [ p… r ] fuera de los límites, pero esto no es
del todo evidente en el código. Como otro ejemplo, es importante que A [ p ] se utilice
como elemento pivote x . Si se usa A [ r ] en su lugar y sucede que A [ r ] también es el
elemento más grande en el subarreglo A [ p…r ], luego TABIQUERÍA vuelve
a QUICKSORT el valor q = r , y QUICKSORT bucles siempre.

ENFOQUE DE DISEÑO DE ALGORITMO


# Definimos un modulo para ingresar mi lista de arreglo
def QUICK_SORT(miLista):
# Llamamos al modulo QUICK_SORT
QUICKSORT(miLista,0,len(miLista)-1)
UNIVERSIDAD NACIONAL SAN ANTONIO ABAD DEL CUSCO
FACULTAD DE INGENIERÍA ELÉCTRICA, ELECTRÓNICA, INFORMÁTICA Y MECÁNICA
ESCUELA PROFESIONAL DE INGENIERÍA INFORMATICA Y DE SISTEMAS

# Modulo de ordenación QUICKSORT


def QUICKSORT(miLista,inicio,fin):
# Si inicio es menor que fin
if (inicio < fin):
# Asignamos a q el modulo de particionar para partir el arreglo
q = PARTICIONAR(miLista,inicio,fin)
# Realizamos la ordenacion partiendo en dos arreglos
QUICKSORT(miLista,inicio,q-1)
QUICKSORT(miLista,q + 1,fin)

# Modulo de particionar el arreglo de números


def PARTICIONAR(miLista,p,r):
# Asignamos al pivot el numero en posicion cero del arreglo
pivot = miLista[p]
i=p+1
j=r
terminado = False
while not terminado:
# Si i es menor que j y el valor de la posicion en i sea menor
igual al pivot
while i <= j and miLista[i] <= pivot:
# Incrementa i en 1
i += 1
# Si j es mayor que i y el valor de la posicion en j sea mayor
igual al pivot
while j >= i and miLista[j] >= pivot:
# Decrementa j en 1
j -= 1
if j < i :
terminado = True
else:
# Intercambiamos los valores miLista[i] y miLista[j]
miLista[i], miLista[j] = miLista[j], miLista[i]

# Intercambiamos los valores miLista[p] y miLista[j]


miLista[p], miLista[j] = miLista[j], miLista[p]

# Regresamos el valor de j
return j

# Iniciamos la lista inicial


ListaDeNumeros = [34,93,19,58,34,12]
print("-------Arreglo Original-------")
print("ListaDeNumeros=",ListaDeNumeros)

# Realizamos la ordenación por QUICKSORT


QUICK_SORT(ListaDeNumeros)
UNIVERSIDAD NACIONAL SAN ANTONIO ABAD DEL CUSCO
FACULTAD DE INGENIERÍA ELÉCTRICA, ELECTRÓNICA, INFORMÁTICA Y MECÁNICA
ESCUELA PROFESIONAL DE INGENIERÍA INFORMATICA Y DE SISTEMAS

# Mostramos lista ordenada


print("-------Arreglo Ordenado-------")
print("ListaOrdenada=",ListaDeNumeros)

COMPLEJIDAD DEL ALGORITMO


Partición en peor de los casos:

El peor de caso para la ordenación rápida ocurre cuando la rutina de partición produce
una región con n - 1 elementos y una con solo 1 elemento. (Esta afirmación se
demuestra en la sección 8.4.1.) Supongamos que esta partición desequilibrada surge en
cada paso del algoritmo. Dado que la partición cuesta ( n ) tiempo y comportamiento
T (1) = (1), la recurrencia del tiempo de ejecución es

T ( n ) = T ( n - 1) + ( n ).

Para evaluar esta recurrencia, observamos que T (1) = (1) y luego iteramos:

Obtenemos la última línea al observar que es la serie aritmética (3.2). La figura


de abajo se muestra un árbol de recursividad para esta ejecución en el peor de los casos
de Quicksort.

Por lo tanto, si la partición está desequilibrada al máximo en cada paso recursivo del
algoritmo, el tiempo de ejecución es ( n 2 ). Por lo tanto, el peor tiempo de ejecución
de Quicksort no es mejor que el de inserción. Además, el tiempo de ejecución ( n 2 )
ocurre cuando la matriz de entrada ya está completamente ordenada, una situación
común en la que la ordenación por inserción se ejecuta en el tiempo O ( n ).
UNIVERSIDAD NACIONAL SAN ANTONIO ABAD DEL CUSCO
FACULTAD DE INGENIERÍA ELÉCTRICA, ELECTRÓNICA, INFORMÁTICA Y MECÁNICA
ESCUELA PROFESIONAL DE INGENIERÍA INFORMATICA Y DE SISTEMAS

Partición en mejor de los casos:

Si el procedimiento de partición produce dos regiones de tamaño n / 2, Quicksort se


ejecuta mucho más rápido. La recurrencia es entonces

T ( n ) = 2 T ( n / 2) + ( n ),

que por el caso 2 del teorema maestro tiene la solución T ( n ) = Θ ( n lg(n) ). Por lo
tanto, esta partición en el mejor de los casos produce un algoritmo mucho más
rápido. La figura siguiente muestra el árbol de recursividad para esta ejecución en el
mejor de los casos de Quicksort.

Intuición para el caso promedio:

Para desarrollar una noción clara del caso promedio para clasificación rápida, debemos
hacer una suposición sobre la frecuencia con la que esperamos encontrar las diversas
entradas. Una suposición común es que todas las permutaciones de los números de
UNIVERSIDAD NACIONAL SAN ANTONIO ABAD DEL CUSCO
FACULTAD DE INGENIERÍA ELÉCTRICA, ELECTRÓNICA, INFORMÁTICA Y MECÁNICA
ESCUELA PROFESIONAL DE INGENIERÍA INFORMATICA Y DE SISTEMAS

entrada son igualmente probables. Discutiremos este supuesto en la siguiente sección,


pero primero exploremos sus ramificaciones.

Cuando ejecutamos la ordenación rápida en una matriz de entrada aleatoria, es poco


probable que la partición siempre ocurra de la misma manera en todos los niveles, como
ha supuesto nuestro análisis informal. Esperamos que algunas de las divisiones estén
razonablemente bien equilibradas y otras bastante desequilibradas.

En el caso medio, PARTICIÓN produce una mezcla de divisiones "buenas" y


"malas". En un árbol de recursividad para una ejecución de caso promedio
de PARTICIÓN, las divisiones buenas y malas se distribuyen aleatoriamente por todo el
árbol. Supongamos, por el bien de la intuición, sin embargo, que las divisiones buenas y
malas alternan niveles en el árbol, y que las divisiones buenas son divisiones en el
mejor de los casos y las divisiones malas son divisiones en el peor de los casos. La
figura que se muestra las divisiones en dos niveles consecutivos en el árbol de
recursividad. En la raíz del árbol, el costo de la partición es n y los subarreglos
producidos tienen tamaños n - 1 y 1: el peor de los casos. En el siguiente nivel, el
subarreglo de tamaño n - 1 se divide en el mejor de los casos en dos subarreglos de
tamaño ( n- 1) / 2. Supongamos que el costo de la condición de contorno es 1 para el
subarreglo de tamaño 1.

La combinación de la división mala seguida de la división buena produce tres


subarreglos de tamaños 1, ( n -1) / 2 y ( n - 1) / 2 a un costo combinado de 2 n - 1
= Θ( n ). Ciertamente, esta situación no es peor que la figura de la derecha, es decir, un
solo nivel de partición que produce dos subarreglos de tamaños ( n - 1) / 2 + 1 y ( n - 1)
/ 2 a un costo de n = Θ( n ). Sin embargo, esta última situación está casi equilibrada,
ciertamente mejor que 9 a 1. Intuitivamente, el Θ( n ) costo de la mala división se puede
absorber en Θ( n) costo de la buena división, y la división resultante es buena. Por lo
tanto, el tiempo de ejecución de Quicksort, cuando los niveles alternan entre divisiones
buenas y malas, es como el tiempo de ejecución solo para divisiones buenas:
todavía O ( n lg(n) ), pero con una constante ligeramente mayor oculta por
la notación O.
UNIVERSIDAD NACIONAL SAN ANTONIO ABAD DEL CUSCO
FACULTAD DE INGENIERÍA ELÉCTRICA, ELECTRÓNICA, INFORMÁTICA Y MECÁNICA
ESCUELA PROFESIONAL DE INGENIERÍA INFORMATICA Y DE SISTEMAS

EJEMPLO

Nos muestra la lista final ordenada por el algoritmo Quicksort.