Guías de Make it Real
  • Introduction
  • Preparación
    • Conceptos básicos
    • El editor de texto
    • La línea de comandos
    • Git y Github
  • Git
    • Instalación y configuración
    • Conceptos y comandos esenciales
    • Ignorando archivos y carpetas
    • Trabajando con ramas
    • Repositorios remotos
    • Etiquetas
    • Reescribiendo la historia
    • Stashing
    • Github
  • HTML y CSS
    • Introducción a HTML
    • Introducción a CSS
    • Más elementos de HTML
    • Tablas
    • Formularios
    • El modelo de caja en CSS
    • Fondos (backgrounds)
    • Posicionamiento
    • Selectores CSS
    • Bordes, sombras y gradientes
    • Media Queries
    • Unidades en CSS
    • Flexbox
  • Bootstrap 3
    • Primeros pasos
    • Elementos básicos de HTML
    • Componentes
    • La grilla
    • Personalizando Bootstrap
    • Utilizando plantillas
  • Bootstrap 4
    • Primeros pasos
    • Elementos básicos de HTML
    • Componentes
    • La grilla
    • Clases utilitarias
    • Personalizando Bootstrap
  • Ruby
    • Primeros pasos
    • Tipos y operadores
    • Variables y entrada de usuario
    • Condicionales
    • Ciclos
    • Arreglos
    • Más cadenas de texto
    • Hashes
    • Métodos
    • Manipulación de archivos
    • Gemas
  • Programación Orientada a Objetos en Ruby
    • Clases y objetos
    • Métodos y atributos de clase
    • Herencia
    • Módulos
    • Excepciones
  • JavaScript I
    • Primeros pasos
    • Tipos y operadores
    • Variables
    • Condicionales
    • Ciclos
    • Arreglos
    • Más cadenas de texto
    • Funciones
    • Objetos literales
    • Manipulación de archivos
  • JavaScript en el navegador
    • Primeros pasos
    • Manipulando HTML
    • Escuchando eventos
    • Local Storage
    • History API
    • Canvas
    • Notificaciones Web
    • Audio y Video
    • Arrastrar y soltar
    • JSON
    • Realizando peticiones HTTP
  • jQuery
    • Primeros pasos
    • Manipulando HTML
    • Escuchando eventos
    • Plugins
    • Realizando peticiones con AJAX
  • JavaScript II
    • Prototipos
    • Librerías (Node.js)
    • ES6
    • Uso de this (call, apply, bind)
    • Programación funcional
    • Scope, hoisting, closures
    • Programación asincrónica
    • Testing
  • HTTP y Sinatra
    • Primeros pasos con Sinatra
    • El protocolo HTTP
    • Rutas
    • Formularios
    • Cookies y sesión
  • Bases de datos
    • Bases de datos relacionales
    • SQL
    • DDL
    • MongoDB
  • Ruby on Rails I
    • Primeros pasos
    • Arquitectura
    • Rutas
    • Layouts y rendering
    • ActiveRecord - Modelos
    • ActiveRecord - Migraciones
    • ActiveRecord - Validaciones
    • ActiveRecord - Asociaciones
    • ActiveRecord - Scopes
    • ActiveRecord - Callbacks
    • Recursos REST
    • Formularios
    • Autenticación con Devise
    • Sass y Bootstrap
    • Envío de correos
    • Carga de imágenes
    • Seeds
    • Heroku
  • Ruby on Rails II
    • Usando JavaScript (y jQuery) en Rails
    • Testing en Ruby
    • Testing en Rails
    • Creando una Web API
    • Web Sockets
  • Express.js
    • Primeros Pasos
    • El protocolo HTTP
    • Rutas
    • Vistas
    • Middlewares y manejo de errores
    • Formularios
    • Cookies y sesión
  • Express.js II
    • Mongoose
    • Web Sockets
    • Autenticación
    • Envío de correos
    • Cargar imágenes
    • Deployment
    • Testing
    • Creando una Web API
  • React
    • Primeros pasos
    • JSX
    • Componentes
    • Más sobre estado
    • Formularios
    • Peticiones HTTP con Axios
    • React Hooks
    • React Context
    • React Bootstrap
    • React Router
    • Carga de Imágenes
    • Testing
    • Estructura de carpetas
    • Componentes de clase
  • Redux
    • Primeros pasos
    • Action creators
    • Usando la librería react-redux
    • Middlewares
    • Operaciones asincrónicas con redux-thunk
    • Combinando funciones reductoras
    • Testing
    • Redux Tool Kit
  • Algoritmos
    • Describiendo un algoritmo
    • Complejidad (Big-O)
    • Estructuras de datos
    • Recursión
    • Ordenamiento
    • Búsqueda
    • Programación dinámica
  • Python
    • Primeros Pasos
    • Tipos y Variables
    • Funciones
    • Control de Flujo
    • Listas
    • Ciclos
    • Diccionarios, Tuplas y Sets
  • NumPy
    • Primeros Pasos
    • Arreglos
    • Arreglos Multidimensionales
    • Estadística con NumPy
    • Distribución Estadística
  • Pandas
    • Primeros Pasos
    • Inspección y Selección de Datos
    • Modificando Dataframes
    • La Función Lambda
    • Aggregates en Pandas
    • Múltiples Tablas
Powered by GitBook
On this page
  • Notación Big-O
  • Complejidad lineal - O(n)
  • Complejidad exponencial - O(n^2), O(n^3), etc.
  • Complejidad logarítmica O(log n)
  • Complejidad constante - O(1)
  • Escenarios (peor, mejor y promedio)
  • Complejidad espacial
  1. Algoritmos

Complejidad (Big-O)

PreviousDescribiendo un algoritmoNextEstructuras de datos

Last updated 2 years ago

La complejidad de un algoritmo nos permite entender cómo se va a comportar el algoritmo cuando incrementemos la cantidad de datos de entrada.

Por ejemplo, en un algoritmo que ordena una lista, la complejidad nos va a permitir saber cómo se va a comportar ese algoritmo cuando tenga 100,000 o 1 millón de elementos.

Notación Big-O

La complejidad del algoritmo es independiente de la velocidad del computador en el que se ejecuta y se define utilizando la notación Big-O. La idea es conocer cuántas operaciones se necesitan a medida que aumentan los datos de entrada.

Complejidad lineal - O(n)

A medida que aumentan los datos el número de operaciones aumenta de forma proporcional. Por ejemplo, si necesitamos 1 operaciones por cada dato, vamos a necesitar 10 operaciones para 10 datos y 100 operaciones para 100 datos.

La siguiente gráfica muestra la relación entre el número de datos (eje x) y el número de operaciones (eje y):

Complejidad lineal

El ejemplo del capítulo anterior en el que describimos una búsqueda simple en un arreglo es un ejemplo de una complejidad lineal O(n).

También puede ocurrir que recibamos dos listas como datos de entrada y debamos recorrerlas de forma independiente. En este caso la complejidad sería O(n+m) donde n es la longitud de la primera lista y m la longitud de la segunda lista.

Complejidad exponencial - O(n^2), O(n^3), etc.

A medida que aumenta la cantidad de datos, el número de operaciones crece de forma exponencial. Por ejemplo, una complejidad cuadrática (O(n^2)) si para un dato necesitamos 2 operaciones, para 2 datos vamos a necesitar 4 operaciones, para 3 datos 9 operaciones y así sucesivamente.

En la vida real la complejidad exponencial ocurre cuando tenemos ciclos anidados. Dos ciclos anidados generan una complejidad O(n^2), tres ciclos anidados O(n^3) y así sucesivamente.

También puede ocurrir que recibamos dos listas que debamos recorrer de forma anidada. En este caso la complejidad sería O(n*m) donde n es la longitud de la primera lista y m la longitud de la segunda lista.

Nota: No confundir O(n*m) que es exponencial con O(n+m) que es lineal.

Complejidad logarítmica O(log n)

A medida que aumenta la cantidad de datos, el número de operaciones aumenta, pero no de forma proporcional a los datos.

En la vida real la complejidad logarítmica se da en casos en los que no es necesario recorrer todos los elementos. Por ejemplo, para adivinar un número de 1 a 100 podemos intentar con 50 y preguntar si el número es mayor o menor. Si es mayor intentamos con 75 y repetimos el proceso acercándonos cada vez más a la respuesta.

Complejidad constante - O(1)

A medida que aumenta la cantidad de datos el número de operaciones se mantiene constante.

O(1) significa que sólo se ejecuta una operación, O(2) significa que se ejecutan dos operaciones, O(3) tres operaciones y así sucesivamente. Pero el número de operaciones no es importante, lo importante es que, independiente del número de datos de entrada, el rendimiento va a ser constante.

Una operación puede ser una asignación de una variable, una comparación, o algún cálculo aritmético (suma, resta, multiplicación, división, etc.), entre otros.

Escenarios (peor, mejor y promedio)

Cuando se habla de la notación Big-O nos podemos referir al peor, mejor o al escenario promedio. Por ejemplo, en el algoritmo de búsqueda del capítulo anterior que nos permite encontrar un elemento en una lista:

  • El peor escenario asume que el elemento se va a encontrar en la última posición.

  • El mejor escenario asume que el elemento se va a encontrar en la primera posición.

  • El escenario promedio asume que el elemento se va a encontrar en la mitad de la búsqueda.

Aunque existen notaciones para expresar el mejor escenario y el escenario promedio, es más conservador, común y fácil referirse al peor escenario cuando se habla de complejidad de un algoritmo como lo hemos hecho en este capítulo.

Complejidad espacial

La complejidad espacial es la cantidad de memoria que requiere el algoritmo. Algunas veces es posible reducir la complejidad temporal incrementando la complejidad espacial y viceversa.

Por ejemplo, un algoritmo que utiliza una variable adicional es O(1). Un algoritmo que utiliza una lista adicional es O(n).

Complejidad exponencial
Complejidad logarítmica