














Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Encuentra los documentos específicos para los exámenes de tu universidad
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
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
1 / 22
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!















Ejercicios de Eficiencia Algor´ıtmica (Notaci´on O Grande)
13 derecha = buscar ( objetivo + 1) - 1 14 15 if izquierda <= derecha : 16 return [ izquierda , derecha ] 17 return [ -1 , -1]
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 -
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
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 []
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 ]
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 -
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
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
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 -
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]
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 -
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 -
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 -
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
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
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
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
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 )
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
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 } " )
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
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 ()
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 ]
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 ]
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
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
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 ]
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
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 ]
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)
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)
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 )
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
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 )
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 -
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
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
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
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 )
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 )