Tarea 1 Unidad III


Recursividad.
 Un programa o subprograma que se llama a si mismo se dice que es recursivo.
 El concepto de recursividad está ligado, en los lenguajes de programación, al  concepto de procedimiento o función. Un procedimiento o función es recursivo  cuando durante una invocación a él puede ser invocado a su vez él mismo.
 La recursividad es una de las formas de control más importantes en la  programación. Los procedimientos recursivos son la forma más natural de  representación de muchos algoritmos.
 Un razonamiento recursivo tiene dos partes: la base y la regla recursiva de  construcción. La base no es recursiva y es el punto tanto de partida como de  terminación de la definición.

Tipos de Recursividad.

Recursión Directa e Indirecta.

Directo: El subprograma se llama directamente a si mismo.
Indirecta: Un programa llama a otro subprograma y este a su vez al primero

Recursividad Infinita

 Es muy importante que toda función recursiva  tenga un caso en el que no se llame a sí misma, o
las llamadas serían infinitas y el programa no  tendría fin.
 Por eso, siempre una función recursiva tiene una condición inicial en la que no debe llamarse a sí misma.

Diferencias entre recursión e iteración.

La recursividad y la iteración (ejecución en bucle) están muy relacionadas, cualquier acción que pueda realizarse con la recursividad puede realizarse con iteración y viceversa. Normalmente, un cálculo determinado se prestará a una técnica u otra, sólo necesita elegir el enfoque más natural o con el que se sienta más cómodo.
Tanto la iteración como la recursión se basan en una estructura de control:
- La iteración utiliza una estructura repetitiva
- La recursión utiliza una estructura de selección.
La iteración y la recursión implican ambas repetición:
- La iteración utiliza explícitamente una estructura repetitiva
- La recursión consume la repetición mediante llamadas repetidas.
La iteración y la recursión implican cada una un test mientras que la recursión  termina cuando se reconoce un caso base o la condición de salida se alcanza.

Ventajas y desventajas.

Ventajas de la Recursión.

- Soluciones simples, claras
- Soluciones elegantes.
- Soluciones a problemas complejos.

Desventajas de la Recursión:

- INEFICIENCIA
-Sobrecarga asociada con las llamadas a subalgoritmos
 Una simple llamada puede generar un gran número de llamadas recursivas. (Fact(n) genera n llamadas recursivas)
 ¿La claridad compensa la sobrecarga?
 El valor de la recursividad reside en el hecho de que se puede usar para resolver problemas sin fácil solución iterativa.
- La ineficiencia inherente de algunos algoritmos recursivos.
La recursividad se debe usar cuando sea realmente necesaria, es decir, cuando no exista una solución iterativa simple.

Actividad IV Unidad II

Listas
Definición
Clasificación
Representación grafica y en memoria
Modo cabecera
- Una lista es una estructura de datos lineal que se puede representar simbólicamente como un conjunto de nodos enlazados entre si.
- Por la forma de acceder a sus elementos.
-Por la información utilizada para acceder a sus elementos.
Listas densas. Cuando la estructura que contiene la lista es la que determina la posición del siguiente elemento.

Listas enlazadas: La localización de un elemento es:
- Estará en la dirección k, si es el primer elemento, siendo k conocido.

-Sino es el primer elemento de la lista, estará en una dirección, j, que está contenida en el elemento anterior.

Listas ordinales. La posición de los elementos en la estructura la determina su orden de llegada.

Listas calificadas. Se accede a un elemento por un valor que coincide con el de un determinado campo, conocido como clave. Este tipo de listas se pueden clasificar a su vez en ordenadas o no ordenadas por el campo clave.
Public class ListaS {
Prívate nodo primero;
Prívate nodo ultimo;
Prívate int tamaño;

Public  listas(){
This.primero=null;
This.ultimo=null;
This.tamano=0;
 


Una lista con nodo de cabecera es aquella en la que el primer nodo de la lista estará diferenciando de los demás. Una lista con nodo cabecera satisface el requerimiento: cada nodo que tiene un elemento tiene un nodo anterior. Esto simplifica las operaciones de eliminación e inserción, pues no hay que tratar los casos especiales para listas vacías.
Se simplifica el código y aumenta la velocidad a cambio de un despreciable aumento de espacio.



Positivo:

Las listas permiten modelar diversas entidades del mundo real, puede implementarse en soportes informáticos de diferentes maneras. Las listas que son un conjunto de nodos tienen cierta relación, los nodos también tienen un valor, cada una tiene su dirección, cuando nosotros reservamos un espacio de memoria, y por ejemplo cuando ya está en la memoria y cada celda y cada una tiene un valor. Las listas se pueden decir que cada nodo es un eslabón de la cadena.

Negativo:

La declaración de una lista mediante una matriz implica conocer de antemano el número (o al menos el orden de magnitud) de elementos que va a almacenar, pudiendo darse las circunstancias de que si se declara pequeño podría desbordarse su capacidad o, en caso contrario, declararlo desproporcionadamente elevado provocaría un decremento de eficiencia.
Otro problema asociado es el tratamiento de los elementos eliminados. Dado que en el caso de no informar, de alguna manera, de la inexistencia de dicho elemento el nodo previamente ocupado (y ahora no válido) quedaría como no disponible.

Interesante:

En el caso de java, se utilizan nodos que son una clase cualquiera que creas, con unos campos dedicados a guardar información, y otro campo que apunta a otro objeto de la clase que has creado, que a su vez contiene información y un enlace a otro nodo, de forma que a partir de uno, puedes avanzar al siguiente y así sucesivamente.

Conclusión:
Una lista con nodo cabecera satisface el requerimiento: cada nodo que contiene un elemento tiene un nodo anterior. Esto simplifica las operaciones de eliminación e inserción, pues no hay que tratar los casos especiales para listas vacías, conocemos muchas cosas interesantes.

Bibliografía:




Tarea IV Actividad II

Listas 

Una LISTA es un conjunto ordenado de elementos homogéneos, en la que no hay restricciones de acceso, la introducción y borrado de elementos puede realizarse en cualquier posición de la misma.

Representación gráfica:


Representación en Memoria:



Tipos o Clasificación. Listas simples enlazadas. 

La lista enlazada básica es la lista enlazada simple la cual tiene un enlace por nodo. Este enlace apunta al siguiente nodo en la lista, o al valor NULL o a la lista vacía, si es el último nodo. 

Lista Doblemente Enlazada

Un tipo de lista enlazada más sofisticado es la lista doblemente enlazada o lista enlazadas de dos vías. Cada nodo tiene dos enlaces: uno apunta al nodo anterior, o apunta al valor NULL si es el primer nodo; y otro que apunta al nodo siguiente, o apunta al valor NULL si es el último nodo. 

Listas enlazadas circulares 

En una lista enlazada circular, el primer y el último nodo están unidos juntos. Esto se puede hacer tanto para listas enlazadas simples como para las doblemente enlazadas. Para recorrer una lista enlazada circular podemos empezar por cualquier nodo y seguir la lista en cualquier dirección hasta que se regrese hasta el nodo original. Desde otro punto de vista, las listas enlazadas circulares pueden ser vistas como listas sin comienzo ni fin. Este tipo de listas es el más usado para dirigir buffers para “ingerir” datos, y para visitar todos los nodos de una lista a partir de uno dado.

Listas enlazadas circulares simples.

Cada nodo tiene un enlace, similar al de las listas enlazadas simples, excepto que el siguiente nodo del último apunta al primero. Como en una lista enlazada simple, los nuevos nodos pueden ser solo eficientemente insertados después de uno que ya tengamos referenciando  Por esta razón, es usual quedarse con una referencia solamente al último elemento en una lista enlazada circular simple, esto nos permite rápidas inserciones al principio, y también permite accesos al primer nodo desde el puntero del último nodo. 

Lista Enlazada Doblemente Circular

En una lista enlazada doblemente circular, cada nodo tiene dos enlaces, similares a los de la lista doblemente enlazada, excepto que el enlace anterior del primer nodo apunta al último y el enlace siguiente del último nodo, apunta al primero. Como en una lista doblemente enlazada, las inserciones y eliminaciones pueden ser hechas desde cualquier punto con acceso a algún nodo cercano. Aunque estructuralmente una lista circular doblemente enlazada no tiene ni principio ni fin, un puntero de acceso externo puede establecer el nodo apuntado que está en la cabeza o al nodo cola, y así mantener el orden tan bien como en una lista doblemente enlazada. 

Nodo cabecera.

Una lista con nodo de cabecera es aquella en la que el primer nodo de la lista estará diferenciado de los demás. Una lista con nodo cabecera satisface el requerimiento: cada nodo que contiene un elemento tiene un nodo anterior. Esto simplifica las operaciones de eliminación e inserción, pues no hay que tratar los casos especiales para listas vacías. Se simplifica el código y aumenta la velocidad a cambio de un despreciable aumento de espacio. 

Bibliografía. 

- Algoritmos, estructuras de datos y programación orientada a objetos. Escrito por Roberto Flórez Rueda 

- Cómo programar en Java.  Escrito por Harvey M. Deitel, Paul J. Deitel 

- Estructuras de datos: Referencia práctica con orientación a objetos. Escrito por Román Martínez, Elda Quiroga


Tarea 3 Unidad II



Los Algoritmos de pop mejorado

Con Pila Auxiliar

- Bubble Sort (Intercambio directo)

El método de intercambio directo puede trabajar de dos maneras diferentes. 

1. llevando los elementos más pequeños hacia la parte izquierda del arreglo. 

2. llevando los elementos más grandes hacia la parte derecha del mismo. 

La idea básica de este algoritmo consiste en comparar pares de elementos adyacentes e intercambiarlos entre sí hasta que todos se encuentren ordenados. Se realizan N-1 pasadas, transportando en cada una de las mismas el menor o mayor elemento (Según sea el caso) su posición ideal. Al final de las N-1 pasadas los elementos del arreglo estarán ordenados. 

Lo siguiente, es una implementación en Pseudocódigo, donde A es un arreglo de N elementos 

BURBUJA(A,N)

{I, J y AUX son variables de tipo entero}

1. Repetir con I desde 2 hasta N

1.1 Repetir con J desde N hasta I

1.1.1 Si A [J-1] > A [J] entonces

Hacer AUX? A [J-1] A [J-1] ? A [J]

A[J] ? AUX

1.1.2 {Fin del condicional del paso 1.1.1}

1.2 {Fin del ciclo del paso 1.1}

2. {Fin del ciclo del paso 1}

Con Corrimientos

· Insertion Sort

Este es uno de los métodos más sencillos. Consta de tomar uno por uno los elementos de un arreglo y recorrerlo hacia su posición con respecto a los anteriormente ordenados. Así empieza con el segundo elemento y lo ordena con respecto al primero. Luego sigue con el tercero y lo coloca en su posición ordenada con respecto a los dos anteriores, así sucesivamente hasta recorrer todas las posiciones del arreglo. Este es el algoritmo: 

- Procedimiento Insertion Sort

Este procedimiento recibe el arreglo de datos a ordenar a[] y altera las posiciones de sus elementos hasta dejarlos ordenados de menor a mayor. N representa el número de elementos que contiene a[]. 

paso 1: [Para cada pos. del arreglo] For i <- 2 to N do 

paso 2: [Inicializa v y j] v <- a[i] j <- i.

paso 3: [Compara v con los anteriores] While a[j-1] > v AND j>1 do

paso 4: [Recorre los datos mayores] Set a[j] <- a[j-1], paso 5: [Decrementa j] set j <- j-1. paso 5: [Inserta v en su posición] Set a[j] <- v.

paso 6: [Fin] End.

- Selection Sort

El método de ordenamiento por selección consiste en encontrar el menor de todos los elementos del arreglo e intercambiarlo con el que está en la primera posición. Luego el segundo mas pequeño, y así sucesivamente hasta ordenar todo el arreglo.

- Procedimiento Selection Sort

paso 1: [Para cada pos. del arreglo]

paso 2: [Inicializa la pos. del menor]

For i <- 1 to N do

menor <- i

paso 3: [Recorre todo el arreglo]

paso 4: [Si a[j] es menor]
For j <- i+1 to N do If a[j] < a[menor] then
paso 5: [Reasigna el apuntador al menor] min = j paso 6: [Intercambia los datos de la pos. min y posición i] Swap(a, min, j).

paso 7: [Fin] End.

Actividad 2 Unidad II



Positivo:

Esta caracterizada por ser una secuencia de los elementos donde se utilizan los algoritmos push y pop, va auxiliada con la estructura de uno de ellos que es FIFOS.

Negativo:

Presenta muchas desventajas pues si eliminamos un elemento de nuestra cola, (el primero justamente) tendríamos que recorrer todos los siguientes elementos una posición adelante y esta manera seria muy lenta de implementar pues que pasa si son 1000 elementos, eso es mucho tiempo perdido, entonces es por eso que usamos dos variables que me digan dónde empieza y dónde terminan los elementos de la cola, dos variables enteras que llamaremos inicio y fin.

Interesante:

Es interesante saber que dentro de la Estructura de Datos una “Cola” va de la mano con los algoritmos de push y pop para que su función sea precisa y adecuada, de tal modo los elementos sean guardados de manera adecuada.

BIBLIOGRAFIA




Tarea 2 Unidad II

Definición de cola

Una cola (también llamada fila) es una estructura de datos, caracterizada por ser una secuencia de elementos en la que la operación de inserción push se realiza por un extremo y la operación de extracción pop por el otro. También se le llama estructura FIFO (del inglés First In First Out), debido a que el primer elemento en entrar será también el primero en salir.

Las colas se utilizan en sistemas informáticos, transportes y operaciones de investigación (entre otros), dónde los objetos, personas o eventos son tomados como datos que se almacenan y se guardan mediante colas para su posterior procesamiento. Este tipo de estructura de datos abstracta se implementa en lenguajes orientados a objetos mediante clases, en forma de listas enlazadas.

Usos concretos en cola

La particularidad de una estructura de datos de cola es el hecho de que sólo podemos acceder al primer y al último elemento de la estructura. Así mismo, los elementos sólo se pueden eliminar por el principio y sólo se pueden añadir por el final de la cola.

Ejemplos de colas en la vida real serían: personas comprando en un supermercado, esperando para entrar a ver un partido de béisbol, esperando en el cine para ver una película, una pequeña peluquería, etc. La idea esencial es que son todas líneas de espera.

Operaciones

- Crear: se crea la cola vacía.

- Encolar (añadir, entrar, insertar): se añade un elemento a la cola. Se añade al final de esta.

- Desencolar (sacar, salir, eliminar): se elimina el elemento frontal de la cola, es decir, el primer elemento que entró.

- Frente (consultar, front): se devuelve el elemento frontal de la cola, es decir, el primer elemento que entró.

Implementación en java:

Public void inserta (Elemento x) { Nodo Nuevo;

Nuevo = new Nodo(x, null);

If (NodoCabeza == null) { NodoCabeza = Nuevo;

} Else {

NodoFinal. Siguiente = Nuevo;

}



NodoFinal = Nuevo;

}

Public Elemento cabeza () throws IllegalArgumentException {

If (NodoCabeza == null) {

Throw new IllegalArgumentException ();

} else {

Return NodoCabeza.Info;

}

}

Public Cola () {

// Devuelve una Cola vacía NodoCabeza = null; NodoFinal = null;

Tipos de cola

- Colas circulares (anillos): en las que el último elemento y el primero están unidos.

- Colas de prioridad: En ellas, los elementos se atienden en el orden indicado por una prioridad asociada a cada uno. Si varios elementos tienen la misma prioridad, se atenderán de modo convencional según la posición que ocupen. Hay 2 formas de implementación:

1. Añadir un campo a cada nodo con su prioridad. Resulta conveniente mantener la cola ordenada por orden de prioridad.

2. Crear tantas colas como prioridades haya, y almacenar cada elemento en su cola.

- Bicolas: son colas en donde los nodos se pueden añadir y quitar por ambos extremos; se les llama DEQUE (Double Ended QUEue). Para representar las bicolas lo podemos hacer con un array circular con Inicio y Fin que apunten a cada uno de los extremos. Hay variantes:

- Bicolas de entrada restringida: Son aquellas donde la inserción sólo se hace por el final, aunque podemos eliminar al inicio ó al final.

- Bicolas de salida restringida: Son aquellas donde sólo se elimina por el final, aunque se puede insertar al inicio y al final.

Actividad I Unidad II


Lo positivo: Una pila puede realizar diversas funciones las cuales logran crear, apilar, desapilar, cimar y vaciar cada una de las cosas con las cuales se esté trabajando.

Lo negativo: Lo malo de una pila es que al momento de que lo quieras ocupar puede que el “Pop” haya sido eliminado ya que una de las instrucciones de la pila es eliminar todo nodo que no se lee en un cierto tiempo.

Lo interesante: Una Pila es un lugar donde se almacenan datos, al igual que en un Array, pero una Pila tiene una filosofía de entrada y salida de datos, esta filosofía es la LIFO (Last In First Out, en español, ultimo en entrar, primero en salir). Esta estructura de datos tiene muchas aplicaciones debido a su simplicidad.

BIBLIOGRAFÍA:



Estructuras de datos y algoritmos con Java, Autor: Adam Drozdek