You are on page 1of 25

UNIVERSIDAD NACIONAL DEL ALTIPLANO

FACULTAD DE INGENIERÍA MECANICA


ELECTRICA, ELECTRONICA Y SISTEMAS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMAS

CURSO:
Análisis y Diseño de Algoritmos

TEMA:
Estructura de Datos para Algoritmos

PRESENTADO POR:
Mamani Charca, Lady Patricia
Quispe Ccallo, Lisbet Charo
Pacsi Quispecondori, Leidy Verónica
Medina Ticona, Yessenia

DOCENTE:
Alave Aguilar, Mariela

SEMESTRE:
CUARTO PERIODO II

PUNO – PERÚ
2018
INDICE

ESTRUCTURA DE DATOS PARA ALGORITMOS ............................................................. 3


INTRODUCCION................................................................................................................... 3
ESTRUCTURA DE DATOS .................................................................................................. 4
ALGORITMOS ....................................................................................................................... 5
LOS MÁS REPRESENTATIVOS EN ESTRUCTURA DE DATOS PARA LOS
ALGORITMOS SON LOS SIGUIENTES: .......................................................................... 5
GRAFOS ............................................................................................................................... 5
MATRICES........................................................................................................................... 5
PILAS Y COLAS .................................................................................................................. 6
PILAS .................................................................................................................................... 6
COLAS .................................................................................................................................. 8
PUNTEROS ........................................................................................................................ 10
ESTRUCTURAS O REGISTROS ...................................................................................... 13
LISTAS ............................................................................................................................... 16
ARBOLES........................................................................................................................... 20
BIBLIOGRAFÍA..................................................................................................................... 25
ESTRUCTURA DE DATOS PARA
ALGORITMOS
INTRODUCCION

La Estructura de Datos es uno de los temas centrales de estudio en el área de


computación, las cuales se mantienen vigentes a lo largo del tiempo.

Hoy en día necesitamos conocer los orígenes de la computación, el cómo usar una
estructura de datos, que es la base que nos ayudara a construir soluciones robustas y útiles
para los diversos problemas.

Este trabajo está realizado con la finalidad de informar de que trata la estructura de datos
para algoritmos, se dará a conocer que es una estructura de datos, que es un algoritmo;
así mismo se dará a conocer los algoritmos más representativos y explicando cada uno de
estos en cómo es que funcionan, para el mayor entendimiento se brindara algunos
ejemplos.
ESTRUCTURA DE DATOS
Un entero puede ser muy útil si necesitamos un contador, una suma o un índice en
un programa, pero generalmente también tenemos que tratar con datos que tienen muchas
partes tales como una lista. Cuando la información de un programa está formada de partes,
tenemos que considerar una estructura de datos adecuada.

Las estructuras de datos tienen algunas características propias. Primero, pueden ser
descompuestas en sus elementos componentes. Segundo, la forma de colocar los
elementos es una característica de la estructura que afectará a cómo se accede a cada
elemento. Tercero, la forma de colocar los elementos y la forma en la que se accede a
ellos puede ser encapsulada.

Por ejemplo en la vida real una biblioteca puede descomponerse en sus elementos, los
libros. La colección de libros puede colocarse de varias formas: todos agrupados, en orden
alfabético, por temas, etc. Obviamente la forma en que se ubican en la biblioteca
particular a la que nos estamos refiriendo, no se deja que cada una se sirva sus libros. Si
alguien quiere un libro, le da su petición al bibliotecario, quien hace la entrega de la lista
de libros pertinentes.

La estructura de datos “biblioteca” está compuesta por elementos (libros) colocados de


forma particular. Por ejemplo, puede estar ordenada sobre la base del sistema decimal de
Dewey(es un sistema de clasificación de bibliotecas. Fue desarrollado por
Melvil Dewey). El acceso a un libro concreto requiere el conocimiento de la forma en
que son situados los libros. El usuario de la biblioteca no tiene porqué conocer este
método de acceso, porque la estructura ha sido encapsulada: el acceso de los usuarios a
los libros se hace sólo a través del bibliotecario.

Usaremos este mismo método para las estructuras de datos de nuestros programas. Una
estructura de datos se definirá como la forma lógica de colocar los elementos, combinados
con el conjunto de operaciones que necesitamos para acceder a los elementos.
ALGORITMOS
Un algoritmo se puede definir como una secuencia de instrucciones que
representan un modelo de solución para determinado tipo de problemas. O bien como un
conjunto de instrucciones que realizadas en orden conducen a obtener la solución de un
problema.

CARACTERISTICAS DE LOS ALGORITMOS:

 Es preciso sin dar lugar a ambigüedades.


 Es definido esto quiere decir que si se sigue un algoritmo dos veces, se obtendrá el
mismo resultado.
 Es finito porque se debe de determinar en algún momento.
 Puede tener 0 o más elementos de entrada.
 Debe de producir un resultado, quiere decir que los datos de salida serán los
resultados de efectuar las instrucciones.

LOS MÁS REPRESENTATIVOS EN ESTRUCTURA DE DATOS PARA LOS


ALGORITMOS SON LOS SIGUIENTES:
GRAFOS
Un grafo en el ámbito de las ciencias de la computación es un tipo abstracto de datos, que
consiste en un conjunto de nodos y un conjunto de arcos que establecen relaciones entre
los nodos.

Formalmente, un grafo se define como G = (V, E), siendo V un conjunto cuyos elementos
son los vértices del grafo y, E uno cuyos elementos son las aristas, las cuales son pares
de elementos en V.

MATRICES

Las matrices o como algunos las llaman "arreglos multidimensionales" son una estructura
de datos bastante similar a los vectores o arreglos. De hecho, una matriz no es más que
una serie de vectores contenidos uno en el otro, es decir, una matriz es un vector cuyas
posiciones son otros vectores. En términos generales, una matriz es una estructura
conformada por filas y columnas, idealmente más de dos filas y columnas, de hecho,
podemos decir que si una "matriz" tiene una única fila o una única columna, entonces
estamos hablando de un vector y no una matriz como tal.
La intersección de una fila y una columna de la matriz son las casillas y cada una de ellas
podrá poseer información, simple o compleja. Un vector posee una única fila y de este
modo un grupo de vectores unidos conforman una matriz, llegando a una conclusión que
una matriz es un vector conformado por otra serie de vectores.

La sintaxis para declarar una matriz en C++ es la siguiente:

tipoDato nombreMatriz[filas][columnas];

Declaración de una matriz en C++:


int myMatriz1[10][5];
float myMatriz2[5][10];
string myMatriz3[15][15];
bool myMatriz4[1000][3];

PILAS Y COLAS
Las pilas y colas son estructuras de datos que se utilizan generalmente para simplificar
ciertas operaciones de programación.

PILAS
Una pila (stack en inglés) es una lista ordenada o estructura de datos en la que el modo
de acceso a sus elementos es de tipo LIFO (Last In Firts Out), último en entrar, primero
en salir; que permite almacenar y recuperar datos.

Operaciones de las pilas

Las operaciones que se pueden realizar con una pila son:

Push: para insertar un elemento.

Pop: para extraer un elemento

Vacía: Función booleana que indica si la pila está vacía o no.

Un pila tiene la forma:


Struct Nodo{
Dato int dato;
NODO
*siguiente Nodo *siguiente;

};
Para Insertar elementos en la pila, solo hay que seguir 4 pasos:

1° Crear el espacio en memoria para almacenar un nodo.

2° Cargar el valor dentro del nodo (dato).

3° Cargar el puntero pila dentro del nodo (*siguiente).

4° Asignar el nuevo nodo a pila.

Dato
*siguiente NODO

Dato
*siguiente

Dato
*siguiente

NULL

Para quitar elementos de una Pila, igualmente hay que seguir 4 pasos:

1° Crear una variable *aux de tipo Nodo.

2. Igualar el n a aux-dato.

3. Pasar pila a siguiente nodo.

4° Eliminar aux.
Aplicaciones de las pila

Las pilas se utilizan en muchas aplicaciones que utilizamos con frecuencia. Por
ejemplo, la gestión de ventanas en Windows (cuando cerramos una ventana siempre
recuperamos la que teníamos detrás). Otro ejemplo es la evaluación general de cualquier
expresión matemática para evitar tener que calcular el número de variables temporales
que hacen falta. Por ejemplo

COLAS
Las colas también son llamadas FIFO (First In First Out), que quiere decir “el primero
que entra es el primero que sale”.

Colas simples: Se inserta por un sitio y se saca por otro, en el caso de la cola simple se
inserta por el final y se saca por el principio. Para gestionar este tipo de cola hay que
recordar siempre cual es el siguiente elemento que se va a leer y cuál es el último elemento
que se ha introducido.

Colas circulares: En las colas circulares se considera que después del último elemento
se accede de nuevo al primero. De esta forma se reutilizan las posiciones extraídas, el
final de la cola es a su vez el principio, creándose un circuito cerrado.

Colas con prioridad: Las colas con prioridad se implementan mediante listas o arrays
ordenados .No nos interesa en este caso que salgan en el orden de entrada sino con una
prioridad que le asignemos. Puede darse el caso que existan varios elementos con la
misma prioridad, en este caso saldrá primero aquel que primero llego (FIFO).

Una cola tiene la siguiente forma:

FIN
Dato Struct Nodo{
NODO
*siguiente int dato;

Nodo *siguiente;

dato };

*siguiente

dato
FRENTE
*siguiente
NULL

Para insertar elementos en una cola, solo hay que seguir 3 pasos:

1° Crear espacio en memoria para almacenar un nodo

2° Asignar ese nuevo nodo al dato que queremos insertar.

3° Asignar los punteros frente y fin hacia el nuevo nodo.

Para eliminar elementos de una cola solo hay que seguir 3 pasos:

1° Obtener el valor del nodo.

2° Crear un nodo auxiliar y asignarle el frente de la cola.

3° Eliminar el nodo del frente de la cola.


Aplicaciones:

Las colas se utilizan en sistemas informáticas, transportes, en una cola de bancos y


operaciones de investigación. Donde los objetos, personas o eventos son tomados como
datos para su posterior procesamiento. Este tipo de estructura de datos abstracta se
implementa en lenguajes orientados a objetos, en forma de listas enlazadas.

PUNTEROS
1. PUNTEROS (APUNTADOR)
Un puntero es una variable que contiene la dirección de memoria de un dato o de otra
variable que contiene al dato en un arreglo. Esto quiere decir, que el puntero apunta al
espacio físico donde está el dato o la variable. Un puntero puede apuntar a un objeto de
cualquier tipo, como por ejemplo, a una estructura o una función. Los punteros se pueden
utilizar para referencia y manipular estructuras de datos, para referenciar bloques de
memoria asignados dinámicamente y para proveer el paso de argumentos por referencias
en las llamadas a funciones.

1.2. DECLARANDO APUNTADORES

Ya se dijo que un puntero es una variable que guarda la dirección de memoria de otra
variable, haciendo lógica a esto, decimos que un puntero se declara igual que cualquier
otra variable, pero anteponiendo un * (asterisco) antes del nombre de la variable.

Su sintaxis sería:

tipo *NombrePuntero = NULL; Se iguala a NULL para saber que no tiene


asignada ninguna dirección.

Veamos el siguiente código:

#include <stdio.h>

int main()
{
int a=0; //Declaración de variable entera de tipo entero
int *puntero; //Declaración de variable puntero de tipo entero
puntero = &a; //Asignación de la dirección memoria de a
printf("El valor de a es: %d. \nEl valor de *puntero es: %d. \n",a,*puntero);
printf("La dirección de memoria de *puntero es: %p",puntero);

return 0;
}

Igual que cuando usamos un &, en la lectura de datos con scanf, igual de esta forma
lo usamos aquí, tal vez te acordarás que decíamos que las cadenas de caracteres (%s)
no usaban este operador, esto es porque en una cadena de caracteres es un arreglo de
caracteres, por lo que el primer carácter es la dirección de inicio de la cadena.

El operador *, nos permite acceder al valor de la dirección del puntero, en este caso
nos permite acceder al valor que contiene a la variable a. De esta forma "a" y
"*puntero" muestran el mismo dato, pero esto no quiere decir que sea lo mismo, uno
es un entero y el otro un puntero.

La impresión con %p, es para poder imprimir la dirección de memoria en valor


hexadecimal (0x...), también podemos imprimir: ...%p",&a) y funciona de la misma
forma, y es lógico que tanto "a" como "puntero" tienen la misma dirección de
memoria.

¿Diferentes direcciones?

Tal vez notaste que en cada ejecución la dirección de memoria cambia, esto es porque
es el sistema operativo quien está encargado de administrar la memoria y es éste quien
dice qué espacios podrá tomar el programa.

Esto quiere decir que uno no puede asignarle una dirección de memoria a un
puntero directamente, es decir yo no puedo hacer lo siguiente.

int *puntero=0xbfc5b1c8;

Esto no puedo ni debo hacerlo ya que yo no sé que está haciendo esta dirección de
memoria, si el sistema la tiene o no disponible, etc... Pero sí puedo hacer esto:

int *puntero=NULL;
NULL, es el espacio en memoria con dirección 0, esto quiere decir que existe, lo que
significa que le asignamos una dirección válida al puntero, pero el valor que tiene NULL
no se nos permite modificarlo, ya que pertenece al sistema.

1.2. OPERADORES

Ya anteriormente te poníamos algunos ejemplos de cómo asignar la dirección de


memoria a un puntero y de cómo acceder al valor de este.

Operador de Dirección (&): Este nos permite acceder a la dirección de memoria de


una variable.

Operador de Indirección (*): Además de que nos permite declarar un tipo de dato
puntero, también nos permite ver el VALOR que está en la dirección asignada.

PUNTEROS CONSTANTES

Es posible que hayas pensado como declarar un puntero como una constante, tal vez
pensaste en un define, o en un atributo const. Bueno es posible usar el atributo const,
pero para un puntero hay que hacerlo de otra forma.

FORMA ERRADA

int a=10,b=20;
const int *p = &a; //objeto constante y puntero variable
*p = 15; // ERROR: el valor apuntado por p es constante.
p=&b; //Correcto: p pasa a apuntar a un nuevo objeto.

Pero de esta forma no es muy útil declararlo, pues el que hicimos constante fue el
valor al que apunte p, es decir, mejor hubiésemos hecho que el puntero fuese una
constante.

FORMA CORRECTA

int a=10,b=20;
int * const p = &a; //objeto variable y puntero constante
int * const p = &a; //objeto variable y puntero constante
*p = 15; // Correcto: El valor apuntado es variable.
p=&b; //ERROR: p es constante.

1.2. PUNTEROS GENERICOS

Un puntero a cualquier tipo de dato puede convertirse a un puntero del tipo void *.
Por esto un puntero a void *, recibe el nombre de puntero genérico.

En C, se permite la conversión implícita de punteros, pero en C++ esto no es posible,


así que por compatibilidad y buena práctica recomendamos usar la conversión
explícita (cast).

Supongamos:

int *puntero;
funcion (*puntero);
....
void funcion (void *p)
int *q;
q=(int *)p; //En C se podria hacer q = p;

Es decir que un puntero a void se puede usar sin importar el tipo de dato, recuerden
que uno no puede trabajar con punteros que referencia a un tipo de dato diferente,
como lo es un puntero a char, con un puntero a int.

ESTRUCTURAS O REGISTROS
Un registro es una agrupación de datos, los cuales no necesariamente son del mismo tipo.
Se definen con la palabra “struct”.

Para acceder a cada uno de los datos que forman el registro, tanto si queremos leer su
valor como si queremos cambiarlo, se debe indicar el nombre de la variable y el del dato
(o campo) separados por un punto:

Un registro (en programación) es un tipo de dato estructurado formado por la unión de


varios elementos bajo una misma estructura, estos elementos pueden ser o bien datos
elementales (entero, real, carácter) o bien otras estructuras de datos, donde a cada uno de
estos se le llama campo. Por ejemplo si nos piden gestionar la información de un
estudiante (unt) que contenga como campos el nombre, edad, apellidos, sexo, teléfono,
DNI, nro. De cursos, ciclo, que cursos lleva…etc. una de las maneras de afrontar este
problema sería con registros

ARRAYS DE REGISTROS

Hemos guardado varios datos de una persona. Se pueden almacenar los de varias
personas si combinamos el uso de los “struct” con las tablas (arrays) que vimos
anteriormente. La sintaxis no es exactamente la misma, y tendremos que añadir la palabra
"new" en el momento de reservar espacio. Por ejemplo, si queremos guardar los datos de
100 alumnos podríamos hacer:

// Introducción a C++, Nacho Cabanes


// Ejemplo 07.03:
// Array de registros

#include <iostream>
#include <string>
using namespace std;

int main()
{
struct datosPersona
{
string nombre;
char inicial;
int edad;
float nota;
};

datosPersona *persona = new datosPersona[50];

for (int i=0; i<5; i++)


{
cout << "Dime el nombre de la persona " << i << endl;
cin >> persona[i].nombre;
}

cout << "La persona 3 es " << persona[2].nombre << endl;

return 0;
}

La inicial del primer alumno sería “alumnos [0].inicial”, y la edad del último sería
“alumnos [99].edad”.

ESTRUCTURAS ANIDADAS

Podemos encontrarnos con un registro que tenga varios datos, y que a su vez ocurra que
uno de esos datos esté formado por varios datos más sencillos. Para hacerlo desde C++,
incluiríamos un “struct” dentro de otro, así:

#include <iostream>
#include <string>
using namespace std;

struct fechaNacimiento
{
int dia;
int mes;
int anyo;
};

struct datosPersona
{
string nombre;
char inicial;
struct fechaNacimiento diaDeNacimiento;
float nota;
};

int main()
{
datosPersona persona;

persona.nombre = "Ignacio";
persona.inicial = 'I';
persona.diaDeNacimiento.mes = 8;
persona.nota = 7.5;
cout << "La nota es " << persona.nota;

return 0;
}

LISTAS
Guardati(2007) define una lista como una colección de elementos donde cada uno de
ellos, además de almacenar información, almacena la dirección del siguiente elemento.
Una lista es una estructura lineal de datos. Es decir, cada uno de sus componentes tiene
un sucesor y predecesor únicos, con excepción del último y del primero, los cuales
carecen de sucesor y predecesor respectivamente.

Las listas pueden implementarse mediante arreglos resultando así una estructura estática.
Otra alternativa para su implementación es usar memoria dinámica, lo que permite que
dicha característica se propague a la lista, obteniendo una estructura dinámica. Las listas
se analizarán como estructuras dinámicas.

Clasificarse en: listas simplemente enlazadas, listas circulares, listas doblemente


enlazadas y listas circulares doblemente enlazadas.

Listas simplemente enlazadas


Guardati(2007) menciona que las listas enlazadas o simplemente ligadas son estructuras
de datos lineal, dinámica, formada por la colección de elementos llamados nodos. Cada
nodo está formado por dos partes:

 La primera de ellas se utiliza para almacenar información.


 La segunda se usa para guardar la dirección del siguiente nodo.

Una lista enlazada consta de un número indeterminado de elementos y cada elemento


tiene dos componentes (campos), un puntero al siguiente elemento de la lista y un valor,
que pude ser de cualquier tipo.

Clasificación de las listas enlazadas

1. Listas simplemente enlazadas: cada nodo (elemento) contiene un único en lace


que conecta ese al nodo siguiente o sucesor. La lista en eficiente para recorridos
directos.(<<adelante>>).

2. Lista doblemente enlazadas: cada nodo contiene dos enlaces, uno a su nodo
predecesor y el otro a su sucesor. La lista es eficiente tanto en recorrido directo
(<<adelante>>) como en recorrido inverso (<<atrás>>).

3. Lista circular simplemente enlazada: en la que el último elemento (cola) se


enlaza con el primer elemento (cabeza) de tal modo que la lista pude ser recorrida
de modo circular.
4. Lista circular doblemente enlazada: el último elemento se enlaza con el primero
y viceversa. Esta lista puede ser recorrida de modo circular tanto en dirección
directa (<<adelante>>) como inversa (<<atrás>>).

Una lista enlazada consta de un conjunto de nodos. Un nodo consta de un campo dato y
un puntero que apunta al <<siguiente>> elemento de lista.

El primer nodo, frente, es el nodo apuntado por cabeza. La lista encadena nodos juntos
desde el frente al final (cola) de la lista. El final se identifica como el nodo cuyo campo
puntero tiene valor NULL=0. La lista se recorre desde el primer hasta el último nodo; en
cualquier punto del recorrido la posición actual se referencia por el puntero Ptr_actual.
En el caso que la lista no contiene nodo, el puntero cabeza en nulo.

Operaciones en listas enlazadas

 Inicialización o creación, con declaración de los nodos

 Insertar elementos en la lista

 Eliminar elementos en la lista

 Buscar elementos en la lista

 Recorrer la lista

 Comprobar si la lista está vacía

Declaración de un NODO

Una lista enlazada se compone de una serie de nodos enlazadas mediante punteros. Cada
nodo es una combinación de dos partes: un tipo de dato (entero, real, double, carácter,
etc) y un enlace (puntero) al siguiente nodo. En C++ se puede definir un nodo mediante
un nuevo tipo de dato con las palabras reservadas struct o class que contienen las dos
partes citadas
EJEMPLO:
ARBOLES
(Guardati, 2007) Menciona que los árboles son estructuras de datos no lineales. Cada
elemento, conocido con el nombre de nodo, puede tener varios sucesores. En términos
generales, un árbol se define como una colección de nodos donde cada uno, además de
almacenar información, guarda la dirección de sus sucesores. Se conoce la dirección de
uno de los nodos llamado raíz, y a partir de él tiene acceso a todos los otros miembros de
la estructura.

Existen diversas maneras de representar un árbol, las más comunes son: grafos,
anidación de paréntesis y diagramas de Venn.

Árbol representado

Terminología
Hijo: Se dice que un nodo es hijo de otro si este último apunta al primero.

Padre: Se dice que un nodo es padre de otro si este último es apuntado por el primero.

Hermano: Dos nodos son hermanos si son apuntados por el mismo nodo, es decir si
tienen el mismo padre.

Raíz: Se dice que un nodo es raíz si a partir de él se relaciona todos los otros nodos. Si
un árbol no es vacío, entonces tiene un único nodo raíz.

Hoja o terminal. Se dice que un nodo es una hoja del árbol si no tiene hijos.

Interior: Se dice que un nodo es interior si no es raíz ni hoja.

Nivel de un nodo: Se dice que el nivel de un nodo es el número de arcos que deben ser
recorridos, partido de la raíz, para llegar hasta él.

Altura del árbol: Se dice que la altura de un árbol es el máximo de los niveles,
considerando todos sus nodos.

Grado de un nodo: se dice que el grado de nodo es el número de hijos que tiene dicho
nodo.

Grado del árbol: Se dice que el grado de un árbol es el máximo de los grados,
considerando todos sus nodos.

NODO
Necesitamos un nodo que apunte a otros nodos

Propiedades del árbol


1. Longitud de Camino
2. Altura de un nodo
3. Profundidad de un nodo. Nivel
4. Nodos hermanos
5. Orden
Arboles binarios
Un árbol binario es un árbol de grado 2 en el cual sus hijos se identifican como subárbol
izquierdo y subárbol derecho. Por lo tanto, cada nodo almacena información y las
direcciones de sus descendientes. Es un tipo de árbol muy usado, ya que saber el número
máximo de hijos que puede tener cada nodo facilita las operaciones sobre ellos.
Dirección Dirección
Subárbol Información Subárbol
Izquierdo Derecho

Ilustración 1. Ejemplo de árbol binario

Un árbol binario es una estructura recursiva. Un árbol binario se divide en tres


subconjuntos disyuntos
Nodo Raíz
Subárbol izquierdo
Subárbol derecho
Tipos de árboles binarios
Árbol lleno

Árbol completo

Árbol degenerado
Estructura de un árbol binario

Árbol binario de búsqueda


Es aquel que dado un nodo, todos los datos del subárbol izquierdo son menores,
mientras que todos los datos del subárbol derecho son mayores.
BIBLIOGRAFÍA

Guardati, S. (2007). Estructura de datos orientada a objetos. Algoritmos con C++. Mexico:
Industrial Atoto.

Joyanes Aguilar, L. (2006). Programación en C++. algoritmos, estructura de datos y objetos.


Colombia: Segunda Edicion.

https://html.rincondelvago.com/estructura-de-datos_16.html?fbclid=IwAR39KYPFILbf1BAAjw

FhnpZPUsqi9nu1O29lalbkGbotQ2zwXCjLWUShbIc

http://ing.unne.edu.ar/pub/informatica/Alg_diag.pdf

https://www.programarya.com/Cursos/C++/Estructuras-de-Datos/Matrices

You might also like