Estructuras de datos I: Estructuras de datos lineales

Notación O Grande

Arreglos

  • Definición: Colección de elementos, cada uno identificado por al menos un índice o llave.
  • Complejidad espacial: O(n)
  • Complejidad temporal:
    • Acceso y asignación: O(1)

Ventajas

  • Acceso e inserción rápida.
  • No tiene overhead.

Desventajas

  • Se debe conocer previamente el tamaño de la colección.
  • Espacio de memoria contiguo.

Arreglo dinámico

  • DefiniciónColección de elementos, cada uno identificado por al menos un índice o llave donde los elementos pueden ser añadidos o removidos.
  • Complejidad espacial: O(n)
  • Complejidad temporal:
    • Acceso: O(1)
    • Inserción y borrado al inicio y en medio: O(n)
    • Inserción y borrado al final: O(1) amortizado
  • Ejemplo en C++: std::vector

Ventajas

  • Acceso rápido.
  • El tamaño de la colección es dinámica.

Desventajas

  • Cuenta con un overhead.
  • Inserción y borrado (al inicio y en medio) requiere O(n).
  • Espacio de memoria contiguo.
#include <cstring>
#include <string>

template <class T_> class DynamicArray
{
public:
    DynamicArray()
    {
        size = 0;
        capacity = 4;
        dynamicArray = new T_[capacity];
    }

    DynamicArray(unsigned int initialCapacity)
    {
        size = 0;
        capacity = initialCapacity;
        dynamicArray = new T_[capacity];
    }

    ~DynamicArray()
    {
        delete[] dynamicArray;
    }

    void insert(T_ value)
    {
        if(size + 1 > capacity)
        {
            capacity *= 2;
            T_ *tmpDynamicArray = new T_[capacity];

            memmove(tmpDynamicArray, dynamicArray, size * sizeof(T_));

            delete[] dynamicArray;

            dynamicArray = tmpDynamicArray;
        }
        dynamicArray[size++] = value;
    }

    void erase(unsigned int index)
    {
        bool resize = (size - 1 < capacity / 2);
        bool lastElement = (index == size - 1);
        if(resize || !lastElement)
        {
            if(resize)
            {
                capacity /= 2;
            }

            T_ *tmpDynamicArray = new T_[capacity];

            if(!lastElement)
            {
                if(index > 0)
                {
                    memmove(tmpDynamicArray, dynamicArray, (index - 1) * sizeof(T_));
                    memmove(tmpDynamicArray + index - 1, dynamicArray + index,
                            (size - index) * sizeof(T_));
                }
                else if(index == 0)
                {
                    memmove(tmpDynamicArray, dynamicArray + 1, (size - 1) * sizeof(T_));
                }
            }
            else
            {
                memmove(tmpDynamicArray, dynamicArray, (size - 1) * sizeof(T_));
            }

            delete[] dynamicArray;

            dynamicArray = tmpDynamicArray;
        }
        --size;
    }

    const T_ &get(unsigned int index) const
    {
        return dynamicArray[index];
    }

    T_ &operator[](unsigned int index)
    {
        return dynamicArray[index];
    }

    const unsigned int &getSize() const
    {
        return size;
    }

    const unsigned int &getCapacity() const
    {
        return capacity;
    }

private:
    T_ *dynamicArray;
    unsigned int size;
    unsigned int capacity;
};

std::string

  • DefiniciónSecuencia de caracteres.
  • Complejidad espacial: O(n)
  • Complejidad temporal:
    • Adjuntar y concatenación: O(n)
std::string joinWords(std::vector<std::string> words){
    std::string longWord = "";
    for(int i = 0; i < words.size(); ++i)
    {
        longWord += words.at(i);
    }
}

Ejemplo práctico

Lista enlazada simple

  • Definición: Colección de de datos representada como un conjunto de nodos donde cada nodo tiene una referencia al siguiente nodo de la lista.
  • Complejidad espacial: O(n)
  • Complejidad temporal:
    • Acesso: O(n)
    • Inserción y borrado: búsqueda + O(1)

Ventajas

  • Estructura de datos dinámica.
  • La memoria no necesariamente es contigua.
  • Inserción y borrado es fácil de implementar.
  • Reduce el tiempo de acceso y crecimiento en memoria sin necesidad de overhead.

Desventajas

  • La memoria no necesariamente es contigua.
  • Se reserva espacio de memoria para los apuntadores.
  • Acceso secuencial.

Lista doblemente enlazada

  • Definición: Colección de de datos representada como un conjunto de nodos donde cada nodo tiene dos referencias. Una al nodo anterior de la lista y otro al nodo siguiente de la lista.
  • Complejidad espacial: O(n)
  • Complejidad temporal:
    • Acesso: O(n)
    • Inserción y borrado: búsqueda + O(1)

Ventajas

  • Las mismas que una lista enlazada simple.
  • Acceso secuencial en ambas direcciones.

Desventajas

  • La misma que una lista enlazada simple.
  • Reserva más espacio por nodo que una lista enlazada simple.

Estructuras de datos I: Estructuras de datos lineales

By Victor Romero

Estructuras de datos I: Estructuras de datos lineales

  • 917