Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


EJERCICIOS DEPROGRAMACION EN PYTHON - INTRODUCCION A ALGORITMOS BASICOS (PARTE 1), Exámenes de Programación Informática

Este documento es una guía de programación en Python, que cubre algoritmos básicos en tres áreas principales: búsqueda, ordenamiento y eficiencia algorítmica. La sección de búsqueda incluye ejercicios como búsqueda lineal, binaria, en listas rotadas, matrices ordenadas y listas infinitas, con implementaciones detalladas en Python. La parte de ordenamiento aborda métodos como burbuja, selección y sus variantes optimizadas, junto con análisis de estabilidad y rendimiento. Finalmente, la sección de eficiencia algorítmica explora la notación O grande, comparando complejidades temporales y espaciales, y optimizando algoritmos. Cada ejercicio viene con su solución en código Python, explicaciones claras sobre el enfoque utilizado y justificaciones teóricas. El documento es ideal para estudiantes que buscan fortalecer sus habilidades en algoritmos, con ejemplos prácticos y problemas progresivos que van desde lo básico hasta más avanzados como listas circulares o patrones desconocidos.

Tipo: Exámenes

2024/2025

A la venta desde 16/05/2025

Apuntes-UDA
Apuntes-UDA 🇨🇱

5

(2)

392 documentos

1 / 22

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
EJERCICIOS DE PROGRAMACION EN PYTHON -
INTRODUCCION A ALGORITMOS BASICOS (PARTE 1)
Universidad de Atacama - Facultad de Ingenieria
12 de Mayo de 2025
Ejercicios de usqueda (Lineal y Binaria)
1. usqueda Lineal en Lista Desordenada
Dada una lista desordenada de enteros y un valor objetivo, escribe una funci´on que devuelva el
´ındice del valor objetivo si est´a presente en la lista, o 1 si no lo est´a. Debes implementar la
usqueda lineal y justificar por qu´e no se puede usar b´usqueda binaria en este caso.
2. usqueda Binaria en Lista Ordenada
Dada una lista ordenada de enteros y un valor objetivo, implementa la usqueda binaria para
encontrar el ´ındice del valor objetivo. Si el valor no est´a en la lista, devuelve 1. Explica por qu´e
la lista debe estar ordenada para que este algoritmo funcione.
3. usqueda del Primer y ´
Ultimo Ocurrencia
Dada una lista ordenada de enteros con posibles duplicados y un valor objetivo, escribe una
funci´on que devuelva los ´ındices de la primera y ´ultima ocurrencia del valor objetivo usando
usqueda binaria. Si el valor no est´a en la lista, devuelve [1,1].
4. usqueda en una Lista Rotada
Dada una lista ordenada pero rotada (ejemplo: [4,5,6,7,0,1,2]) y un valor objetivo, implementa
una funci´on que encuentre el ´ındice del valor objetivo usando una modificaci´on de la usqueda
binaria. Explica tu soluci´on.
5. usqueda en una Matriz Ordenada
Dada una matriz 2D donde cada fila y columna est´a ordenada en orden ascendente, y un valor
objetivo, implementa una funci´on eficiente para determinar si el valor est´a presente en la matriz.
Usa una variante de la usqueda binaria.
6. usqueda de un Rango en una Lista
Dada una lista ordenada de enteros y un rango [a, b], escribe una funci´on que devuelva todos los
elementos de la lista que caen dentro del rango, utilizando usqueda binaria para optimizar el
proceso.
7. usqueda de un Elemento Cercano
Dada una lista ordenada de enteros y un valor objetivo que puede no estar en la lista, escribe una
funci´on que devuelva el elemento as cercano al valor objetivo. Usa usqueda binaria para lograr
una soluci´on eficiente.
8. usqueda en una Lista Infinita
Simula una lista ¨ınfinita”(donde no conoces el tama˜no de antemano) y un valor objetivo. Im-
plementa una funci´on que encuentre la posici´on del valor objetivo usando una combinaci´on de
usqueda lineal y binaria.
1
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16

Vista previa parcial del texto

¡Descarga EJERCICIOS DEPROGRAMACION EN PYTHON - INTRODUCCION A ALGORITMOS BASICOS (PARTE 1) y más Exámenes en PDF de Programación Informática solo en Docsity!

EJERCICIOS DE PROGRAMACION EN PYTHON -

INTRODUCCION A ALGORITMOS BASICOS (PARTE 1)

Universidad de Atacama - Facultad de Ingenieria

12 de Mayo de 2025

Ejercicios de B´usqueda (Lineal y Binaria)

1. B´usqueda Lineal en Lista Desordenada

Dada una lista desordenada de enteros y un valor objetivo, escribe una funci´on que devuelva el

´ındice del valor objetivo si est´a presente en la lista, o −1 si no lo est´a. Debes implementar la

b´usqueda lineal y justificar por qu´e no se puede usar b´usqueda binaria en este caso.

2. B´usqueda Binaria en Lista Ordenada

Dada una lista ordenada de enteros y un valor objetivo, implementa la b´usqueda binaria para

encontrar el ´ındice del valor objetivo. Si el valor no est´a en la lista, devuelve −1. Explica por qu´e

la lista debe estar ordenada para que este algoritmo funcione.

3. B´usqueda del Primer y ´Ultimo Ocurrencia

Dada una lista ordenada de enteros con posibles duplicados y un valor objetivo, escribe una

funci´on que devuelva los ´ındices de la primera y ´ultima ocurrencia del valor objetivo usando

b´usqueda binaria. Si el valor no est´a en la lista, devuelve [− 1 , −1].

4. B´usqueda en una Lista Rotada

Dada una lista ordenada pero rotada (ejemplo: [4, 5 , 6 , 7 , 0 , 1 , 2]) y un valor objetivo, implementa

una funci´on que encuentre el ´ındice del valor objetivo usando una modificaci´on de la b´usqueda

binaria. Explica tu soluci´on.

5. B´usqueda en una Matriz Ordenada

Dada una matriz 2D donde cada fila y columna est´a ordenada en orden ascendente, y un valor

objetivo, implementa una funci´on eficiente para determinar si el valor est´a presente en la matriz.

Usa una variante de la b´usqueda binaria.

6. B´usqueda de un Rango en una Lista

Dada una lista ordenada de enteros y un rango [a, b], escribe una funci´on que devuelva todos los

elementos de la lista que caen dentro del rango, utilizando b´usqueda binaria para optimizar el

proceso.

7. B´usqueda de un Elemento Cercano

Dada una lista ordenada de enteros y un valor objetivo que puede no estar en la lista, escribe una

funci´on que devuelva el elemento m´as cercano al valor objetivo. Usa b´usqueda binaria para lograr

una soluci´on eficiente.

8. B´usqueda en una Lista Infinita

Simula una lista ¨ınfinita”(donde no conoces el tama˜no de antemano) y un valor objetivo. Im-

plementa una funci´on que encuentre la posici´on del valor objetivo usando una combinaci´on de

b´usqueda lineal y binaria.

9. B´usqueda de un Pico en una Lista

Dada una lista de enteros donde lista[i] ̸= lista[i + 1], encuentra un ”pico”(un elemento mayor

que sus vecinos) utilizando una variante de la b´usqueda binaria. Explica por qu´e la b´usqueda

binaria es aplicable aqu´ı.

10. B´usqueda en una Lista con Saltos

Dada una lista ordenada pero donde algunos elementos han sido desplazados por un ”salto.aleatorio,

escribe una funci´on que encuentre un valor objetivo combinando b´usqueda lineal y binaria.

11. B´usqueda de un Valor en una Lista con Duplicados

Dada una lista ordenada con duplicados, escribe una funci´on que devuelva True si el valor objetivo

est´a presente, pero usando la menor cantidad de comparaciones posible (optimizando la b´usqueda

binaria).

12. B´usqueda de la Ra´ız Cuadrada Entera

Dado un n´umero entero no negativo, encuentra su ra´ız cuadrada entera usando b´usqueda binaria.

Por ejemplo, para 8, la respuesta es 2 (ya que 2^2 = 4 ≤ 8 < 32 = 9).

13. B´usqueda de un Valor en una Lista Circular

Dada una lista circular ordenada (ejemplo: [5, 6 , 7 , 1 , 2 , 3]) y un valor objetivo, implementa una

funci´on que encuentre el ´ındice del valor objetivo usando b´usqueda binaria.

14. B´usqueda de un Elemento Faltante

Dada una lista ordenada de enteros consecutivos con un elemento faltante, escribe una funci´on

que encuentre el elemento faltante usando b´usqueda binaria.

15. B´usqueda de un Valor en una Lista con Errores

Dada una lista ordenada donde algunos elementos pueden estar corruptos (ejemplo: [1, 3 , 2 , 4 , 5]),

escribe una funci´on que encuentre el valor objetivo, asumiendo que la mayor´ıa de los elementos

est´an en su posici´on correcta.

16. B´usqueda de un N´umero en una Lista de Strings

Dada una lista de strings donde cada string representa un n´umero (ejemplo: [”1”, ”3”, ”5”, ”7”])

y un valor objetivo (como string), escribe una funci´on que devuelva el ´ındice del valor objetivo

usando b´usqueda binaria.

17. B´usqueda de un Valor en una Lista con Patr´on Desconocido

Dada una lista donde los elementos siguen un patr´on desconocido pero ordenado (ejemplo:

[10, 20 , 15 , 25 , 30]), escribe una funci´on que encuentre el valor objetivo combinando b´usqueda

lineal y binaria.

18. B´usqueda de un Elemento en una Lista con Restricciones

Dada una lista ordenada y un valor objetivo, pero solo puedes acceder a los elementos de la lista

a trav´es de una funci´on get(index) que tarda O(1), implementa una b´usqueda binaria eficiente.

19. B´usqueda de un Valor en una Lista con Distancia Fija

Dada una lista donde la diferencia entre elementos consecutivos es fija (ejemplo: [3, 6 , 9 , 12]) y un

valor objetivo, escribe una funci´on que encuentre el valor objetivo en tiempo O(log n).

20. B´usqueda de un Valor en una Lista con Pivote Desconocido

Dada una lista ordenada pero con un pivote desconocido (ejemplo: [7, 9 , 1 , 3 , 5]) y un valor objetivo,

implementa una funci´on que encuentre el valor objetivo usando b´usqueda binaria.

34. Ordenamiento por Selecci´on con Detecci´on de Orden

Implementa el ordenamiento por selecci´on pero incluye una verificaci´on inicial para determinar si

la lista ya est´a ordenada, en cuyo caso el algoritmo debe terminar inmediatamente.

35. Ordenamiento Burbuja en una Lista con Valores ´Unicos

Dada una lista de enteros con valores ´unicos, implementa el ordenamiento burbuja y compara su

rendimiento con una lista que contiene duplicados.

36. Ordenamiento por Selecci´on con Memoria Adicional

Implementa una versi´on del ordenamiento por selecci´on que utilice memoria adicional (otra lista)

para construir la lista ordenada, en lugar de intercambiar elementos in-place.

37. Ordenamiento Burbuja con Registro de Intercambios

Modifica el ordenamiento burbuja para que registre todos los intercambios realizados en un archivo

de texto, incluyendo los ´ındices de los elementos intercambiados y sus valores.

38. Ordenamiento por Selecci´on en una Lista Enlazada

Dada una lista enlazada, implementa el algoritmo de ordenamiento por selecci´on para ordenar

sus nodos. Explica los desaf´ıos de trabajar con listas enlazadas.

39. Ordenamiento Burbuja con Par´ametro de Direcci´on

Implementa el ordenamiento burbuja para que acepte un par´ametro ascendente que determine

si la lista debe ordenarse en orden ascendente o descendente.

40. Ordenamiento por Selecci´on con Mezcla de Sub-listas

Divide una lista en dos sub-listas, ord´enalas por separado usando ordenamiento por selecci´on, y

luego m´ezclalas en una sola lista ordenada. Compara este enfoque con ordenar la lista completa

de una vez.

Ejercicios de Eficiencia Algor´ıtmica (Notaci´on O Grande)

41. An´alisis de Complejidad de B´usqueda Lineal

Dada una funci´on de b´usqueda lineal, determina su complejidad temporal en el peor caso, mejor

caso y caso promedio. Explica cada escenario con ejemplos concretos.

42. An´alisis de Complejidad de B´usqueda Binaria

Analiza la complejidad temporal de la b´usqueda binaria en el peor caso y explica por qu´e es

O(log n). Proporciona un ejemplo donde la b´usqueda binaria no sea eficiente.

43. Comparaci´on de Burbuja y Selecci´on

Compara las complejidades temporales de los algoritmos de ordenamiento burbuja y selecci´on.

¿En qu´e casos uno es mejor que el otro? Justifica tu respuesta.

44. Optimizaci´on de un Algoritmo Cuadr´atico

Dado un algoritmo con complejidad O(n^2 ), propone una optimizaci´on para reducir su complejidad

a O(n log n) o mejor. Implementa ambas versiones y compara su rendimiento.

45. Complejidad de un Algoritmo con Bucles Anidados

Dado un algoritmo con tres bucles anidados que recorren una lista de tama˜no n, determina su

complejidad temporal y propone una forma de optimizarlo.

46. An´alisis de Complejidad Espacial

Dada una funci´on que utiliza una lista auxiliar de tama˜no n, determina su complejidad espacial.

Compara con una versi´on que no use memoria adicional.

47. Complejidad de un Algoritmo Recursivo

Analiza la complejidad temporal de un algoritmo recursivo que divide el problema en dos subpro-

blemas de tama˜no n/2 en cada paso. Explica tu razonamiento.

48. Notaci´on O Grande para Operaciones de Lista

Determina la complejidad temporal de las siguientes operaciones en Python: lista.append(),

lista.insert(0, x), lista.pop(), lista.pop(0). Explica cada caso.

49. Complejidad de un Algoritmo con Diferentes Pasos

Dado un algoritmo que primero ordena una lista (O(n log n)) y luego realiza una b´usqueda binaria

(O(log n)), determina su complejidad temporal total.

50. Peor Caso vs. Caso Promedio

Explica la diferencia entre el peor caso y el caso promedio en el an´alisis de algoritmos. Proporciona

un ejemplo donde el peor caso sea significativamente diferente del caso promedio.

51. Complejidad de un Algoritmo con Condicionales

Dado un algoritmo que ejecuta un bucle for pero tiene un condicional que puede terminar el

bucle prematuramente, analiza su complejidad temporal en el peor caso y mejor caso.

52. An´alisis de un Algoritmo de Fuerza Bruta

Dado un algoritmo de fuerza bruta que prueba todas las combinaciones posibles de un conjunto

de datos, determina su complejidad temporal y propone una alternativa m´as eficiente.

53. Complejidad de un Algoritmo con Llamadas a Funciones

Dada una funci´on que llama a otra funci´on de complejidad O(n) dentro de un bucle for de n

iteraciones, determina la complejidad temporal total.

54. Optimizaci´on de un Algoritmo Lineal

Dado un algoritmo con complejidad O(n), ¿es posible optimizarlo a´un m´as? Discute los l´ımites

inferiores y proporciona un ejemplo donde O(n) sea el mejor caso posible.

55. Complejidad de un Algoritmo con Estructuras de Datos

Dado un algoritmo que utiliza un diccionario (hash table) para almacenar datos, analiza su com-

plejidad temporal para operaciones de inserci´on, b´usqueda y eliminaci´on.

56. An´alisis de un Algoritmo con M´ultiples Entradas

Dado un algoritmo que procesa dos listas de tama˜nos n y m, determina su complejidad temporal

y explica c´omo las diferentes relaciones entre n y m afectan el an´alisis.

57. Complejidad de un Algoritmo con Recursi´on M´ultiple

Analiza la complejidad temporal de un algoritmo recursivo que hace dos llamadas recursivas en

cada paso con tama˜nos n − 1 y n − 2.

58. Notaci´on O Grande para Algoritmos de Ordenamiento

Compara las complejidades temporales de los algoritmos de ordenamiento burbuja, selecci´on,

inserci´on, mergesort y quicksort. Explica cu´ando cada uno es preferible.

59. Complejidad de un Algoritmo con Pre-procesamiento

Dado un algoritmo que primero pre-procesa los datos en O(n log n) y luego responde consultas en

O(1), determina su complejidad temporal para k consultas.

60. An´alisis de un Algoritmo en el Mundo Real

Elige un algoritmo utilizado en aplicaciones reales (ejemplo: PageRank de Google) y analiza su

complejidad temporal y espacial. Explica c´omo afecta su eficiencia a la escalabilidad.

13 derecha = buscar ( objetivo + 1) - 1 14 15 if izquierda <= derecha : 16 return [ izquierda , derecha ] 17 return [ -1 , -1]

4. B´usqueda en una Lista Rotada

1 def buscar_en_rotada ( nums , objetivo ) : 2 izquierda , derecha = 0 , len ( nums ) - 1 3 4 while izquierda <= derecha : 5 medio = ( izquierda + derecha ) // 2 6 if nums [ medio ] == objetivo : 7 return medio 8 9 # Mitad izquierda ordenada 10 if nums [ izquierda ] <= nums [ medio ]: 11 if nums [ izquierda ] <= objetivo < nums [ medio ]: 12 derecha = medio - 1 13 else : 14 izquierda = medio + 1 15 # Mitad derecha ordenada 16 else : 17 if nums [ medio ] < objetivo <= nums [ derecha ]: 18 izquierda = medio + 1 19 else : 20 derecha = medio - 1 21 return -

5. B´usqueda en una Matriz Ordenada

1 def buscar_en_matriz ( matriz , objetivo ) : 2 if not matriz : 3 return False 4 5 fila , col = 0 , len ( matriz [0]) - 1 6 7 while fila < len ( matriz ) and col >= 0: 8 if matriz [ fila ][ col ] == objetivo : 9 return True 10 elif matriz [ fila ][ col ] > objetivo : 11 col -= 1 12 else : 13 fila += 1 14 return False

6. B´usqueda de un Rango en una Lista

1 def buscar_en_rango ( lista , a , b ) : 2 def busqueda_binaria_izq ( x ) : 3 izquierda , derecha = 0 , len ( lista ) 4 while izquierda < derecha : 5 medio = ( izquierda + derecha ) // 2 6 if lista [ medio ] < x : 7 izquierda = medio + 1 8 else : 9 derecha = medio 10 return izquierda 11 12 inicio = busqueda_binaria_izq ( a ) 13 fin = busqueda_binaria_izq ( b + 1) - 1 14 15 return lista [ inicio : fin +1] if inicio <= fin else []

7. B´usqueda de un Elemento Cercano

1 def elemento_mas_cercano ( lista , objetivo ) : 2 izquierda , derecha = 0 , len ( lista ) - 1 3 4 while izquierda <= derecha : 5 medio = ( izquierda + derecha ) // 2 6 if lista [ medio ] == objetivo : 7 return lista [ medio ] 8 elif lista [ medio ] < objetivo : 9 izquierda = medio + 1 10 else : 11 derecha = medio - 1 12 13 # Comparar con los elementos m s cercanos 14 if derecha < 0: 15 return lista [0] 16 if izquierda >= len ( lista ) : 17 return lista [ -1] 18 19 if abs ( lista [ izquierda ] - objetivo ) < abs ( lista [ derecha ] - objetivo ) : 20 return lista [ izquierda ] 21 else : 22 return lista [ derecha ]

8. B´usqueda en una Lista Infinita

1 def buscar_en_infinito ( lista , objetivo ) : 2 # Primero encontrar el rango donde p o d r a estar el objetivo 3 izquierda , derecha = 0 , 1 4 while lista [ derecha ] < objetivo : 5 izquierda = derecha 6 derecha *= 2 7 8 # Ahora b s q u e d a binaria e s t n d a r 9 while izquierda <= derecha : 10 medio = ( izquierda + derecha ) // 2 11 if lista [ medio ] == objetivo : 12 return medio 13 elif lista [ medio ] < objetivo : 14 izquierda = medio + 1 15 else : 16 derecha = medio - 1 17 return -

9. B´usqueda de un Pico en una Lista

1 def encontrar_pico ( lista ) : 2 izquierda , derecha = 0 , len ( lista ) - 1 3 4 while izquierda < derecha : 5 medio = ( izquierda + derecha ) // 2 6 if lista [ medio ] > lista [ medio + 1]: 7 derecha = medio 8 else : 9 izquierda = medio + 1 10 return izquierda

Explicaci´on: La b´usqueda binaria es aplicable porque al comparar un elemento con su vecino

derecho, podemos determinar en qu´e mitad del array debe estar el pico.

10. B´usqueda en una Lista con Saltos

12 return medio 13 elif cuadrado < x : 14 izquierda = medio + 1 15 else : 16 derecha = medio - 1 17 18 return derecha # Devuelve el entero menor m s cercano

13. B´usqueda de un Valor en una Lista Circular

1 def buscar_en_circular ( nums , objetivo ) : 2 izquierda , derecha = 0 , len ( nums ) - 1 3 4 while izquierda <= derecha : 5 medio = ( izquierda + derecha ) // 2 6 if nums [ medio ] == objetivo : 7 return medio 8 9 # Mitad izquierda e s t ordenada 10 if nums [ izquierda ] <= nums [ medio ]: 11 if nums [ izquierda ] <= objetivo < nums [ medio ]: 12 derecha = medio - 1 13 else : 14 izquierda = medio + 1 15 # Mitad derecha e s t ordenada 16 else : 17 if nums [ medio ] < objetivo <= nums [ derecha ]: 18 izquierda = medio + 1 19 else : 20 derecha = medio - 1 21 return -

14. B´usqueda de un Elemento Faltante

1 def encontrar_faltante ( lista ) : 2 izquierda , derecha = 0 , len ( lista ) - 1 3 4 while izquierda <= derecha : 5 medio = ( izquierda + derecha ) // 2 6 # Si el elemento en medio es el esperado , el faltante e s t a la derecha 7 if lista [ medio ] == medio + lista [0]: 8 izquierda = medio + 1 9 else : 10 derecha = medio - 1 11 12 return izquierda + lista [0]

15. B´usqueda de un Valor en una Lista con Errores

1 def buscar_con_errores ( lista , objetivo ) : 2 izquierda , derecha = 0 , len ( lista ) - 1 3 4 while izquierda <= derecha : 5 medio = ( izquierda + derecha ) // 2 6 if lista [ medio ] == objetivo : 7 return medio 8 9 # Verificar si el lado izquierdo e s t ordenado 10 if lista [ izquierda ] <= lista [ medio ]: 11 if lista [ izquierda ] <= objetivo < lista [ medio ]: 12 derecha = medio - 1 13 else :

14 izquierda = medio + 1 15 else : 16 if lista [ medio ] < objetivo <= lista [ derecha ]: 17 izquierda = medio + 1 18 else : 19 derecha = medio - 1 20 21 # B s q u e d a lineal como respaldo 22 for i in range ( len ( lista ) ) : 23 if lista [ i ] == objetivo : 24 return i 25 return -

16. B´usqueda de un N´umero en una Lista de Strings

1 def buscar_string_numerico ( lista , objetivo_str ) : 2 objetivo = int ( objetivo_str ) 3 izquierda , derecha = 0 , len ( lista ) - 1 4 5 while izquierda <= derecha : 6 medio = ( izquierda + derecha ) // 2 7 medio_val = int ( lista [ medio ]) 8 9 if medio_val == objetivo : 10 return medio 11 elif medio_val < objetivo : 12 izquierda = medio + 1 13 else : 14 derecha = medio - 1 15 return -

17. B´usqueda de un Valor en una Lista con Patr´on Desconocido

1 def buscar_con_patron ( lista , objetivo ) : 2 # Primero intentar encontrar el p a t r n 3 n = len ( lista ) 4 if n < 3: 5 return -1 # No hay suficiente i n f o r m a c i n 6 7 # Buscar el punto donde se rompe el p a t r n 8 izquierda , derecha = 0 , n - 1 9 while izquierda < derecha : 10 medio = ( izquierda + derecha ) // 2 11 # Verificar si el medio es un pico 12 if lista [ medio -1] < lista [ medio ] > lista [ medio +1]: 13 break 14 elif lista [ medio ] < lista [ medio +1]: 15 izquierda = medio + 1 16 else : 17 derecha = medio - 1 18 19 # Realizar b s q u e d a binaria en ambas mitades 20 idx1 = busqueda_binaria ( lista [: medio +1] , objetivo ) 21 if idx1 != -1: 22 return idx 23 idx2 = busqueda_binaria ( lista [ medio +1:] , objetivo ) 24 if idx2 != -1: 25 return medio + 1 + idx 26 return -

18. B´usqueda de un Elemento en una Lista con Restricciones

1 class ListaRestringida :

14 izquierda , derecha = 0 , len ( lista ) - 1 15 if lista [ pivote ] <= objetivo <= lista [ derecha ]: 16 izquierda = pivote 17 else : 18 derecha = pivote - 1 19 20 # B s q u e d a binaria e s t n d a r 21 while izquierda <= derecha : 22 medio = ( izquierda + derecha ) // 2 23 if lista [ medio ] == objetivo : 24 return medio 25 elif lista [ medio ] < objetivo : 26 izquierda = medio + 1 27 else : 28 derecha = medio - 1 29 return -

Respuestas a los ejercicios de Ordenamiento

21. Ordenamiento Burbuja con Contador de Intercambios

1 def burbuja_contador ( lista ) : 2 n = len ( lista ) 3 intercambios = 0 4 for i in range (n -1) : 5 for j in range (n -1 - i ) : 6 if lista [ j ] > lista [ j +1]: 7 lista [ j ] , lista [ j +1] = lista [ j +1] , lista [ j ] 8 intercambios += 1 9 return intercambios

22. Ordenamiento por Selecci´on con Comparaciones

1 def seleccion_comparaciones ( lista ) : 2 comparaciones = 0 3 n = len ( lista ) 4 for i in range (n -1) : 5 min_idx = i 6 for j in range ( i +1 , n ) : 7 comparaciones += 1 8 if lista [ j ] < lista [ min_idx ]: 9 min_idx = j 10 lista [ i ] , lista [ min_idx ] = lista [ min_idx ] , lista [ i ] 11 return comparaciones

23. Ordenamiento Burbuja Optimizado

1 def burbuja_optimizado ( lista ) : 2 n = len ( lista ) 3 for i in range (n -1) : 4 intercambiado = False 5 for j in range (n -1 - i ) : 6 if lista [ j ] > lista [ j +1]: 7 lista [ j ] , lista [ j +1] = lista [ j +1] , lista [ j ] 8 intercambiado = True 9 if not intercambiado : 10 break

Explicaci´on: La optimizaci´on mejora el rendimiento porque evita pasadas innecesarias cuando

la lista ya est´a ordenada, reduciendo la complejidad en el mejor caso a O(n).

24. Ordenamiento por Selecci´on con Estabilidad

1 def seleccion_estable ( lista ) : 2 n = len ( lista ) 3 for i in range (n -1) : 4 min_idx = i 5 for j in range ( i +1 , n ) : 6 if lista [ j ] < lista [ min_idx ]: 7 min_idx = j 8 # Insertar en lugar de intercambiar 9 valor = lista. pop ( min_idx ) 10 lista. insert (i , valor )

Ejemplo de estabilidad: Al ordenar ‘[(2, ’a’), (1, ’b’), (2, ’c’)]‘ por el primer elemento, se

mantiene el orden relativo de los elementos con clave igual.

25. Ordenamiento Burbuja en Lista Parcialmente Ordenada

1 def burbuja_parcial ( lista ) : 2 n = len ( lista ) 3 pasadas = 0 4 for i in range (n -1) : 5 intercambiado = False 6 for j in range (n -1 - i ) : 7 if lista [ j ] > lista [ j +1]: 8 lista [ j ] , lista [ j +1] = lista [ j +1] , lista [ j ] 9 intercambiado = True 10 pasadas += 1 11 if not intercambiado : 12 break 13 return pasadas

26. Ordenamiento por Selecci´on con Registro de Pasos

1 def seleccion_con_pasos ( lista ) : 2 n = len ( lista ) 3 for i in range (n -1) : 4 min_idx = i 5 for j in range ( i +1 , n ) : 6 if lista [ j ] < lista [ min_idx ]: 7 min_idx = j 8 lista [ i ] , lista [ min_idx ] = lista [ min_idx ] , lista [ i ] 9 print ( f " Paso { i +1}: { lista } " )

27. Ordenamiento Burbuja Bidireccional (Cocktail Sort)

1 def cocktail_sort ( lista ) : 2 n = len ( lista ) 3 izquierda = 0 4 derecha = n - 5 while izquierda < derecha : 6 # Ida ( izquierda a derecha ) 7 for i in range ( izquierda , derecha ) : 8 if lista [ i ] > lista [ i +1]: 9 lista [ i ] , lista [ i +1] = lista [ i +1] , lista [ i ] 10 derecha -= 1 11 12 # Vuelta ( derecha a izquierda ) 13 for i in range ( derecha , izquierda , -1) : 14 if lista [ i ] < lista [i -1]: 15 lista [ i ] , lista [i -1] = lista [i -1] , lista [ i ] 16 izquierda += 1

28. Ordenamiento por Selecci´on con M´ultiples Claves

12 return tiempos 13 14 # Uso : 15 tamanios = [100 , 1000 , 10000] 16 tiempos = medir_tiempo_seleccion ( tamanios ) 17 plt. plot ( tamanios , tiempos ) 18 plt. xlabel ( ’ T a m a o de lista ’) 19 plt. ylabel ( ’ Tiempo ( s ) ’) 20 plt. show ()

33. Ordenamiento Burbuja con L´ımite de Pasadas

1 def burbuja_limitado ( lista , max_pasadas ) : 2 n = len ( lista ) 3 for i in range ( min ( max_pasadas , n -1) ) : 4 for j in range (n -1 - i ) : 5 if lista [ j ] > lista [ j +1]: 6 lista [ j ] , lista [ j +1] = lista [ j +1] , lista [ j ]

34. Ordenamiento por Selecci´on con Detecci´on de Orden

1 def seleccion_inteligente ( lista ) : 2 n = len ( lista ) 3 for i in range (n -1) : 4 ordenado = True 5 min_idx = i 6 for j in range ( i +1 , n ) : 7 if lista [ j ] < lista [ min_idx ]: 8 min_idx = j 9 if lista [ j ] < lista [j -1]: 10 ordenado = False 11 if ordenado : 12 break 13 lista [ i ] , lista [ min_idx ] = lista [ min_idx ] , lista [ i ]

35. Ordenamiento Burbuja en una Lista con Valores ´Unicos

1 def burbuja_unicos ( lista ) : 2 n = len ( lista ) 3 for i in range (n -1) : 4 for j in range (n -1 - i ) : 5 if lista [ j ] > lista [ j +1]: 6 lista [ j ] , lista [ j +1] = lista [ j +1] , lista [ j ] 7 # Rendimiento similar , pero sin elementos iguales para comparar

36. Ordenamiento por Selecci´on con Memoria Adicional

1 def seleccion_con_memoria ( lista ) : 2 ordenada = [] 3 lista_copia = lista. copy () 4 5 while lista_copia : 6 min_val = min ( lista_copia ) 7 ordenada. append ( min_val ) 8 lista_copia. remove ( min_val ) 9 10 return ordenada

37. Ordenamiento Burbuja con Registro de Intercambios

1 def burbuja_con_registro ( lista , archivo ) : 2 n = len ( lista ) 3 with open ( archivo , ’w ’) as f :

4 for i in range (n -1) : 5 for j in range (n -1 - i ) : 6 if lista [ j ] > lista [ j +1]: 7 f. write ( f " Intercambio { j } y { j +1}: { lista [ j ]} <-> { lista [ j +1]}\ n " ) 8 lista [ j ] , lista [ j +1] = lista [ j +1] , lista [ j ]

38. Ordenamiento por Selecci´on en una Lista Enlazada

1 class Nodo : 2 def init ( self , valor ) : 3 self. valor = valor 4 self. siguiente = None 5 6 def seleccion_lista_enlazada ( cabeza ) : 7 actual = cabeza 8 while actual : 9 minimo = actual 10 siguiente = actual. siguiente 11 while siguiente : 12 if siguiente. valor < minimo. valor : 13 minimo = siguiente 14 siguiente = siguiente. siguiente 15 actual. valor , minimo. valor = minimo. valor , actual. valor 16 actual = actual. siguiente 17 return cabeza

Desaf´ıos: No se puede acceder a elementos por ´ındice, requiere recorridos completos para cada

selecci´on.

39. Ordenamiento Burbuja con Par´ametro de Direcci´on

1 def burbuja_direccion ( lista , ascendente = True ) : 2 n = len ( lista ) 3 for i in range (n -1) : 4 for j in range (n -1 - i ) : 5 if ( ascendente and lista [ j ] > lista [ j +1]) or
6 ( not ascendente and lista [ j ] < lista [ j +1]) : 7 lista [ j ] , lista [ j +1] = lista [ j +1] , lista [ j ]

40. Ordenamiento por Selecci´on con Mezcla de Sub-listas

1 def seleccion_mezclado ( lista ) : 2 mitad = len ( lista ) // 2 3 lista1 , lista2 = lista [: mitad ] , lista [ mitad :] 4 5 # Ordenar sublistas 6 for i in range ( len ( lista1 ) -1) : 7 min_idx = i 8 for j in range ( i +1 , len ( lista1 ) ) : 9 if lista1 [ j ] < lista1 [ min_idx ]: 10 min_idx = j 11 lista1 [ i ] , lista1 [ min_idx ] = lista1 [ min_idx ] , lista1 [ i ] 12 13 for i in range ( len ( lista2 ) -1) : 14 min_idx = i 15 for j in range ( i +1 , len ( lista2 ) ) : 16 if lista2 [ j ] < lista2 [ min_idx ]: 17 min_idx = j 18 lista2 [ i ] , lista2 [ min_idx ] = lista2 [ min_idx ] , lista2 [ i ] 19 20 # Mezclar 21 return sorted ( lista1 + lista2 )

3 count = 0 4 for i in range ( n ) : # O ( n ) 5 for j in range ( n ) : # O ( n ) 6 for k in range ( n ) : # O ( n ) 7 count += 1 # Total : O ( n ^3) 8 return count 9 10 # Optimizado O ( n ^2) 11 def triple_bucle_opt ( n ) : 12 count = 0 13 for i in range ( n ) : # O ( n ) 14 for j in range (i , n ) : # O ( n /2) promedio 15 count += ( n - j ) # O (1) 16 return count # Total : O ( n ^2)

46. Complejidad Espacial

1 # Con memoria adicional O ( n ) 2 def cuadrados ( lista ) : 3 resultado = [] # Espacio O ( n ) 4 for x in lista : # Tiempo O ( n ) 5 resultado. append ( x ** 2) # O (1) 6 return resultado 7 8 # Sin memoria adicional O (1) 9 def cuadrados_inplace ( lista ) : 10 for i in range ( len ( lista ) ) : # Tiempo O ( n ) 11 lista [ i ] = lista [ i ] ** 2 # O (1) 12 return lista # Espacio O (1)

47. Algoritmo Recursivo

1 def suma_recursiva ( lista ) : 2 if len ( lista ) == 0: # Caso base O (1) 3 return 0 4 return lista [0] + suma_recursiva ( lista [1:]) # Llamada recursiva O ( n ) 5 # Total : O ( n ) tiempo , O ( n ) espacio ( por slices )

48. Operaciones de Lista

1 # D e m o s t r a c i n de complejidades 2 lista = [1 , 2 , 3] 3 4 # O (1) 5 lista. append (4) # Append al final 6 7 # O ( n ) 8 lista. insert (0 , 0) # Insert al inicio desplaza todos 9 10 # O (1) 11 lista. pop () # Pop del final 12 13 # O ( n ) 14 lista. pop (0) # Pop del inicio desplaza todos

49. Algoritmo con M´ultiples Pasos

1 def proceso_complejo ( lista ) : 2 lista. sort () # O ( n log n ) 3 resultado = [] 4 for x in lista : # O ( n ) 5 if x % 2 == 0: # O (1) 6 resultado. append ( x ** 2) # O (1) 7 return resultado # Total : O ( n log n )

50. Peor Caso vs Caso Promedio

1 def busqueda_condicional ( lista , objetivo ) : 2 for i , x in enumerate ( lista ) : # O ( n ) peor caso 3 if x == objetivo : # O (1) 4 return i # O (1) mejor caso 5 if x > objetivo : # Puede terminar antes 6 break # Caso promedio : O ( n /2) 7 return -

51. Algoritmo con Condicionales

1 def buscar_con_condicion ( lista , condicion ) : 2 for x in lista : # O ( n ) peor caso 3 if condicion ( x ) : # O (1) 4 return x # O (1) mejor caso 5 return None # O ( n ) peor caso

52. Fuerza Bruta vs Optimizado

1 # Fuerza bruta O (2^ n ) 2 def fibonacci_bruto ( n ) : 3 if n <= 1: # O (1) 4 return n 5 return fibonacci_bruto (n -1) + fibonacci_bruto (n -2) # O (2^ n ) 6 7 # Optimizado O ( n ) 8 def fibonacci_opt (n , memo ={}) : 9 if n <= 1: 10 return n 11 if n not in memo : 12 memo [ n ] = fibonacci_opt (n -1 , memo ) + fibonacci_opt (n -2 , memo ) 13 return memo [ n ] # O ( n ) con memoization

53. Llamadas a Funciones

1 def funcion_lineal ( lista ) : # O ( n ) 2 return sum ( lista ) # sum es O ( n ) 3 4 def funcion_cuadratica ( lista ) : # O ( n ^2) 5 total = 0 6 for x in lista : # O ( n ) 7 total += funcion_lineal ( lista ) # O ( n ) 8 return total

54. L´ımite Inferior

1 def maximo ( lista ) : 2 max_val = lista [0] # O (1) 3 for x in lista [1:]: # O ( n ) ( debe recorrer toda la lista ) 4 if x > max_val : # O (1) 5 max_val = x # O (1) 6 return max_val # Total : O ( n ) ( ptimo )

55. Estructuras de Datos

1 # Complejidades de dict 2 mi_dict = {} 3 4 # I n s e r c i n O (1) promedio 5 mi_dict [ ’ clave ’] = ’ valor ’ 6 7 # B s q u e d a O (1) promedio 8 valor = mi_dict. get ( ’ clave ’ , None )