0% encontró este documento útil (0 votos)
50 vistas5 páginas

Algoritmos Básicos: 1. Introducción

El documento presenta un conjunto de algoritmos básicos utilizados en la materia de Algoritmos y Estructuras de Datos II, incluyendo métodos de ordenamiento y búsqueda. Se detallan las precondiciones, postcondiciones y complejidades de cada algoritmo, aunque no se justifica su correctitud ni complejidad. Se incluye pseudocódigo para ilustrar la implementación de los algoritmos mencionados.

Cargado por

klopp1772
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
50 vistas5 páginas

Algoritmos Básicos: 1. Introducción

El documento presenta un conjunto de algoritmos básicos utilizados en la materia de Algoritmos y Estructuras de Datos II, incluyendo métodos de ordenamiento y búsqueda. Se detallan las precondiciones, postcondiciones y complejidades de cada algoritmo, aunque no se justifica su correctitud ni complejidad. Se incluye pseudocódigo para ilustrar la implementación de los algoritmos mencionados.

Cargado por

klopp1772
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Algoritmos básicos

Algoritmos y Estructuras de Datos II, DC, UBA.

1. Introducción
En este apunte presentamos un conjunto de algoritmos básicos que sirven como útiles a la hora de resolver los
ejercicios de algoritmia de la materia (dividir y conquistar y ordenamiento) y también como ejemplos adicionales de
cómo presentar algoritmos.
No se presenta en el apunte la justificacion de correctitud ni de las cotas de complejidad provistas, aunque sí se
asegura que son correctas. Para aprovecharlo mejor, se recomienda leer y entender la idea de los algoritmos y justificar
los órdenes de complejidad. Los elementos para hacerlo están presentes en las clases teóricas de la materia.
En este apunte los índices de un arreglo de tamaño n los usaremos entre 1 y n, ya que dicha notación es más
cómoda para la algoritmia. La traducción a índices entre 0 y n − 1 es directa y fácil, pero debe hacerse con cuidado.

2. Interfaces
Para expresar todos los órdenes de complejidad se utiliza la convención n = tam(A). Para simplificar, la notación
a ≤ x ≤ b es abreviatura de a ≤ x ∧ x ≤ b, y de forma similar para otras combinaciones con < estricto.
Swap(in/out x:nat, in/out y:nat)
Pre {x0 = x ∧ y0 = y}
Pos {y = x0 ∧ x = y0 }
Compl O(1)
PrimeroMayorA(in A:arreglo(nat), in x:nat) → res:nat
Pre {ordenado?(A)}
Pos {1 ≤ res ≤ tam(A) + 1 ∧L (res > 1 ⇒L A[res − 1] ≤ x) ∧ (res ≤ tam(A) ⇒L A[res] > x)}
Compl O(log n)

ÚltimoMenorA(in A:arreglo(nat), in x:nat) → res:nat


Pre {ordenado?(A)}
Pos {0 ≤ res ≤ tam(A) ∧L (res > 0 ⇒L A[res] < x) ∧ (res ≤ tam(A) − 1 ⇒L A[res + 1] ≥ x)}
Compl O(log n)

PosMáxima(in A:arreglo(nat)) → res:nat


Pre {(∃res:nat) 1 ≤ res ≤ tam(A) ∧L ∀j : nat(1 ≤ j < res ⇒L A[j] < A[j + 1]) ∧ (res ≤ j ≤ tam(A) ⇒L A[j] > A[j + 1])}
Pos {1 ≤ res ≤ tam(A) ∧L ∀j : nat(1 ≤ j < res ⇒L A[j] < A[j + 1]) ∧ (res ≤ j ≤ tam(A) ⇒L A[j] > A[j + 1])}
Compl O(log n)
BubbleSort(in/out A:arreglo(nat))
Pre {A0 = A}
Pos {ordenado?(A) ∧ esPermutación(A, A0 )}
Compl O(n2 )

InsertionSort(in/out A:arreglo(nat))
Pre {A0 = A}
Pos {ordenado?(A) ∧ esPermutación(A, A0 )}
Compl O(n2 )
SelectionSort(in/out A:arreglo(nat))
Pre {A0 = A}
Pos {ordenado?(A) ∧ esPermutación(A, A0 )}
Compl O(n2 )

1
Algoritmos y Estructuras de Datos II 1er cuatrimestre de 2012

QuickSort(in/out A:arreglo(nat))
Pre {A0 = A}
Pos {ordenado?(A) ∧ esPermutación(A, A0 )}
Compl O(n2 )

Merge(out A:arreglo(nat), in B:arreglo(nat), in C:arreglo(nat))


Pre {ordenado?(B) ∧ ordenado?(C)}
Pos {ordenado?(A) ∧ esPermutación(A,concatenar(B,C))}
Compl O(n)

MergeSort(in/out A:arreglo(nat))
Pre {A0 = A}
Pos {ordenado?(A) ∧ esPermutación(A, A0 )}
Compl O(n log n)
MaxHeapify(in/out A:arreglo(nat))
Pre {A0 = A}
Pos {esMaxHeap(A) ∧ esPermutación(A, A0 )}
Compl O(n)

HeapSort(in/out A:arreglo(nat))
Pre {A0 = A}
Pos {ordenado?(A) ∧ esPermutación(A, A0 )}
Compl O(n log n)

CountingSort(in/out A:arreglo(nat))
Pre {A0 = A}
Pos {ordenado?(A) ∧ esPermutación(A, A0 )}
Compl O(n + máx(A))
InsertarOrdenado(in/out A:arreglo(nat), in x:nat)
Pre {ordenado?(A) ∧ A0 = A}
Pos {(∃B :arreglo(nat)) tam(B) = 1 ∧L B[1] = x ∧ esPermutación(A, concatenar(A0 ,B)) ∧ ordenado?(res)}
Compl O(n)
dónde,
ordenado?(A) ≡ (∀i : nat)1 ≤ i < tam(A) ⇒L A[i] ≤ A[i + 1]
esMaxHeap?(A) ≡ (∀i : nat)(1 ≤ i ∧ 2 × i ≤ tam(A)) ⇒L A[i] ≥ A[2 × i])∧
(1 ≤ i ∧ 2 × i + 1 ≤ tam(A) ⇒L A[i] ≥ A[2 × i + 1])
esPermutación(A, B) ≡ tam(A) = tam(B) ∧ (∃P : arreglo(nat)) tam(P ) = tam(A) ∧ esPermutación1N(P )∧
(∀i : nat)1 ≤ i ≤ tam(A) ⇒L A[i] = B[P [i]]
esPermutación1N(A) ≡ (∀i : nat)1 ≤ i ≤ tam(A) ⇒ (∃j : nat)1 ≤ j ≤ tam(A) ∧L A[j] = i
concatenar(A, B) ≡ función del mundo de TADs que concatena dos arreglos.

3. Algoritmos
Las funciones de arreglo CrearArreglo, Subarreglo y Copiar las suponemos dadas. Subarreglo da una vista
con aliasing de una porción del arreglo, es decir, Subarreglo(A, i, j)[k] es la misma variable que A[i + k − 1] y
tam(Subarreglo(A, i, j)) es j − i + 1 (siempre restringido a 1 ≤ i ≤ j ≤ tam(A)). CrearArreglo y Copiar toman
tiempo O(n) dónde n es el tamaño del arreglo y Subarreglo toma tiempo O(1).
En varios de los casos, especialmente las funciones recursivas, el pseudocódigo dado no responde a una implemen-
tación especialmente eficiente en términos de constantes y ahorro de memoria, sino a una forma pedagógica de ilustrar
el algoritmo cumpliendo con la cota prometida de complejidad temporal.

Swap(in/out x:nat, in/out y:nat)


nat aux ← x
x←y
y ← aux

PrimeroMayorA(in A:arreglo(nat), in x:nat) → res:nat

2/5
Algoritmos y Estructuras de Datos II 1er cuatrimestre de 2012

nat i ← 1, j ← tam(A) + 1
while i < j − 1 do
nat m ← (i + j)/2
if A[m] > x then
j←m
else
i←m
end if
end while
if A[i] > x then
res ← i
else
res ← j
end if

ÚltimoMenorA(in A:arreglo(nat), in x:nat) → res:nat


nat i ← 0, j ← tam(A)
while i < j − 1 do
nat m ← (i + j)/2
if A[m] < x then
i←m
else
j←m
end if
end while
if A[j] < x then
res ← j
else
res ← i
end if

PosMáxima(in A:arreglo(nat)) → res:nat


nat i ← 1, j ← tam(A)
while i < j − 1 do
nat m ← (i + j)/2
if A[m − 1] < A[m] then
i←m
else
j←m
end if
end while
if A[i] > A[i + 1] then
res ← i
else
res ← i + 1
end if

BubbleSort(in/out A:arreglo(nat))
for i ← 1 to tam(A) do
for j ← i + 1 to tam(A) do
if A[i] > A[j] then
Swap(A[i], A[j])
end if
end for
end for

InsertionSort(in/out A:arreglo(nat))

3/5
Algoritmos y Estructuras de Datos II 1er cuatrimestre de 2012

for i ← 2 to tam(A) do
nat j ← i, x ← A[i]
while j > 1 ∧ A[j − 1] > x do
A[j] ← A[j − 1], j ← j − 1
end while
A[j] ← x
end for

SelectionSort(in/out A:arreglo(nat))
for i ← 1 to tam(A) do
nat m ← i
for j ← i + 1 to tam(A) do
if A[m] > A[j] then
m←j
end if
end for
Swap(A[i], A[m])
end for

QuickSort(in/out A:arreglo(nat))
nat p ← número al azar entre 1 y tam(A)
Swap(A[p], A[1])
nat i = 1, j = tam(A)
while i < j do
if A[i] < A[i + 1] then
Swap(A[i], A[i + 1]), i ← i + 1
else
Swap(A[j], A[i + 1]), j ← j − 1
end if
end while
if i > 1 then
QuickSort(Subarreglo(A, 1, i − 1))
end if
if i < tam(A) then
QuickSort(Subarreglo(A, i + 1, tam(A)))
end if

Merge(out A:arreglo(nat), in B:arreglo(nat), in C:arreglo(nat))


nat iB ← 1, iC ← 1
A ← CrearArreglo(tam(B) + tam(C))
for i ← 1 to tam(A) do
if iB ≤ tam(B) ∧ (iC > tam(C) ∨ B[iB ] < C[iC ]) then
A[i] ← B[iB ], iB ← iB + 1
else
A[i] ← C[iC ], iC ← iC + 1
end if
end for

MergeSort(in/out A:arreglo(nat))
if tam(A) > 1 then
nat m ← tam(A)/2
arreglo(nat) B ← Copiar(Subarreglo(A, 1, m)), C ← Copiar(Subarreglo(A, m + 1, tam(A)))
MergeSort(B)
MergeSort(C)
Merge(A, B, C)
end if

4/5
Algoritmos y Estructuras de Datos II 1er cuatrimestre de 2012

MaxHeapify(in/out A:arreglo(nat))
nat i ← tam(A)
while i > 0 do
nat j ← i
while 2j ≤ tam(A) do
nat k ← 2j
if 2j + 1 ≤ tam(A) ∧ A[2j + 1] > A[k] then
k ← 2j + 1
end if
if A[j] < A[k] then
Swap(A[k], A[j]), j ← k
else
j ← tam(A) + 1
end if
end while
i←i−1
end while

HeapSort(in/out A:arreglo(nat))
MaxHeapify(A)
nat i ← tam(A)
while i > 1 do
Swap(A[i], A[1])
nat j ← 1
while 2j ≤ tam(A) do
nat k ← 2j
if 2j + 1 ≤ tam(A) ∧ A[2j + 1] > A[k] then
k ← 2j + 1
end if
if A[j] < A[k] then
Swap(A[k], A[j]), j ← k
else
j ← tam(A) + 1
end if
end while
i←i−1
end while

CountingSort(in/out A:arreglo(nat))
nat m ← 0
for i ← 1 to tam(A) do
m ← máx(m, A[i])
end for
arreglo(nat) C ← CrearArreglo(m + 1)
for i ← 1 to tam(A) do
C[A[i] + 1] ← C[A[i] + 1] + 1
end for
nat i ← 1
for x ← 0 to m do
for t ← 1 to C[x + 1] do
A[i] ← x, i ← i + 1
end for
end for

InsertarOrdenado(in/out A:arreglo(nat), in x:nat)


arreglo(nat) B ← CrearArreglo(1), res ← CrearArreglo(tam(A) + 1)
B[1] ← x
Merge(A, A, B)

5/5

También podría gustarte