jueves, 2 de octubre de 2014

3.3.4 Cola de Prioridad: Definición y Aplicaciones

Una Cola de Prioridad es una estructura de datos que: permite:
1. La inserción de elementos en la cola con una determinada prioridad .
2. Consultar el siguiente elemento de la cola de acuerdo a la prioridad de sus elementos.
3. Obtener y eliminar el siguiente elemento de la cola de acuerdo a la prioridad de sus elementos.
 Particularidades de Java:
La prioridad de los elementos no es explícita, viene implícita de acuerdo al criterio de comparación de los elementos. El mínimo elemento es el más prioritario
Estructura de Datos: Cola de Prioridad
 Cola de Prioridad: Colección de Datos
que tienen Asociado cierta información (prioridad) que determina el orden en el que se accede a dichos datos.
package modelos;
public interface ColaPrioridad<E extends Comparable<E>> {
void insertar(E x);
E recuperarMin();
E eliminarMin();
boolean esVacia();
}
Precondición: Los métodos recuperarMin() y eliminarMin()

se tienen que aplicar sobre Cola Prioridad no vacías.

3.3.3 Tipos De Colas Cola Simple Cola Circular Y Colas Dobles

Cola dobles

La bicola o doble cola es un tipo de cola especial que permiten la inserción y eliminación de elementos de ambos extremos de la cola. Puede representarse a partir de un vector y dos índices, siendo su representación más frecuente una lista circular doblemente enlazada.
Esta estructura es una cola bidimensional en que las inserciones y eliminaciones se pueden realizar en cualquiera de los dos extremos de la bicola. Gráficamente representamos una bicola de la siguiente manera:





Existen dos variantes de la doble cola:
Doble cola de entrada restringida.
Doble cola de salida restringida.
La primera variante sólo acepta inserciones al final de la cola, y la segunda acepta eliminaciones sólo al frente de la cola
Algoritmo de Inicialización
F < -- 1
A <-- 0

Algoritmo para Insertar
Si A=máximo entonces mensaje (overflow) en caso contrario
 A <--A+1
cola[A]<-- valor

Algoritmo para Extraer
Si F&gtA entonces
mensaje (underflow)
en caso contrario
mensaje (frente/atrás)
si frente entonces
x <-- cola[F]
F <-- F+1
en caso contrario
x <-- cola[A]
A <-- A-1


Esta estructura es un conjunto de elementos donde a cada uno de ellos se les asigna una prioridad, y la forma en que son procesados es la siguiente:
Un elemento de mayor prioridad es procesado al principio.
Dos elementos con la misma prioridad son procesados de acuerdo al orden en que fueron insertados en la cola.

Algoritmo para Insertar
x <--1
final<--verdadero
para i desde 1 hasta n haz
Si cola[i]&gtprioridad entonces
x <--i
final <--falso
salir
si final entonces
x <--n+1
para i desde n+1 hasta x+1
cola[i] <--prioridad
n <-- n+1

Algoritmo para Extraer
Si cola[1]=0 entonces
mensaje(overflow)
en caso contrario
procesar <--cola[1]
para i desde 2 hasta n haz
cola[i-1] <--cola[1]
n <-- n-1


Las operaciones que nosotros podemos realizar sobre una cola son las siguientes:
·         Inserción.
·         Extracción.
Las inserciones en la cola se llevarán a cabo por atrás de la cola, mientras que las eliminaciones se realizarán por el frente de la cola (hay que recordar que el primero en entrar es el primero en salir).

Existen dos variantes de la doble cola:

Doble cola de entrada restringida.-
Este tipo de doble cola acepta solamente la inserción de elementos por un extremo; mientras que puede eliminar por ambos.

Doble cola de salida restringida.-
Este tipo de doble cola acepta solamente la eliminación de elementos por un extremo; mientras que puede insertar por ambos.
Cola Circular

Una cola circular o anillo es una estructura de datos en la que los elementos están de forma circular y cada elemento tiene un sucesor y un predecesor. Los elementos pueden cosultarse, añadirse y eliminarse unicamente desde la cabeza del anillo que es una posición distinguida. Existen dos operaciones de rotaciones, una en cada sentido, de manera que la cabeza del anillo pasa a ser el elemento sucesor, o el predecesor, respectivamente, de la cabeza actual.
Para solucionar el problema de desperdicio de memoria se implementaron las colas circulares, en las cuales existe un apuntador desde el último elemento al primero de la cola.
La representación gráfica de esta estructura es la siguiente:






La condición de vacío en este tipo de cola es que el apuntador F sea igual a cero.
Las condiciones que debemos tener presentes al trabajar con este tipo de estructura son las siguientes:
·         Over flow, cuando se realice una inserción.
·         Under flow, cuando se requiera de una extracción en la cola.
·         Vacio

ALGORITMO DE INICIALIZACIÓN
F < -- 0
A<-- 0

ALGORITMO PARA INSERTAR
Si (F+1=A) ó (F=1 y A=máximo) entonces
mensaje (overflow)
en caso contrario
inicio
si A=máximo entonces
A<--1
cola[A]<-- valor
en caso contrario
A <--A+1
cola[A]<-- valor
si F=0 entonces
F <-- 1
fin

ALGORITMO PARA EXTRAER
Si F=0 entonces
mensaje (underflow) en caso contrario
x <-- cola[F]
si F=A entonces
F <-- 0
A<-- 0
en caso contrario
si F=máximo entonces

F <--1 en caso contrario F <-- F+1

3.3.2 Operaciones básicas de las colas

Pues en las colas como en toda estructura de datos las operaciones principales son insertar y eliminar, aunque en varias implementaciones de colas puedan recibir nombres diferentes.
Insertar
La inserción en las colas se realiza por la cola de las mismas, es decir, se inserta al final de la estructura.
Para llevar a cabo esta operación únicamente hay que reestructurar un par de punteros, el último nodo debe pasar a apuntar al nuevo nodo (que pasará a ser el último) y el nuevo nodo pasa a ser la nueva cola de la cola.

Vamos a verlo gráficamente sobre la siguiente cola:
Si a esta cola le añadimos el elemento 0, la cola resultante sería:
Borrar
El borrado es una operación muy simple en las colas. Esta operación supone extraer la cabeza de la cola, ya que es el elemento que más tiempo lleva en la estructura. Para llevar a cabo esta operación únicamente hay que extraer el elemento situado en la cabeza de la cola y avanzar el puntero cabeza una posición, para que de esta forma la nueva cabeza sea el segundo elemento que más tiempo lleva en la cola.
Si realizamos la operación eliminar sobre la colas de 4 elementos del último gráfico el resultado sería el siguiente:


Una diferencia importante entre las colas y las listas, es que en las colas no se puede borrar un elemento cualquiera, se borra siempre el que está en la cabeza de la cola.

3.3.1 MEMORIA ESTATICA Y DINAMICA

.
memoria





Es un espacio lógico para guardar información.
La memoria (también llamada almacenamiento) se refiere a parte de los componentes que forman parte de una COMPUTADORA, Son dispositivos que retienen DATOS informáticos durante algún intervalo de tiempo. Las memorias de computadora proporcionan unas de las principales funciones de la computación moderna, la retención o almacenamiento de información. Es uno de los componentes fundamentales de todas las computadoras modernas que, acoplados al CPU.
ESTÁTICA
La forma más fácil de almacenar el contenido de una variable en memoria en tiempo de ejecución es en memoria estática o permanente a lo largo de toda la ejecución del programa. O sea,  que no se modifica al menos en tiempo de ejecución.
No todos los objetos (variables) pueden ser almacenados estáticamente.
Para que un objeto pueda ser almacenado en memoria estática su tamaño (número de bytes necesarios para su almacenamiento) ha de ser conocido en tiempo de compilación, como consecuencia de esta condición no podrán almacenarse en memoria estática:

dinámica
Su tamaño puede variar durante la ejecución del programa y puede ser liberado mediante la función free. O sea que se modifica permanentemente.
Memoria estática.-
Las técnicas de asignación de memoria estática son sencillas.
La asignación de memoria puede hacerse en tiempo de compilación y los objetos están vigentes desde que comienza la ejecución del programa hasta que termina.
En los lenguajes que permiten la existencia de subprogramas, y siempre que todos los objetos de estos subprogramas puedan almacenarse estáticamente se aloja en la memoria estática un registro de activación correspondiente a cada uno de los subprogramas.

Estos registros de activación contendrán las variables locales, parámetros formales y valor devuelto por la función.

miércoles, 1 de octubre de 2014

3.3 Colas

Son aquellas que solo tiene 2 operaciones, Push(Inserción) y Pop(Eliminación). Push solo se puede efectuar por un extremo llamado Frente y Pop por el extremo Llamado Final. Sin Embargo se le pueden aplicar todas las operación al igual que a las listas.
Recorrido
Definición:
Ya que las colas son FIFO(First in - First Out) el Recorrido se hace sacando el primer dato que se inserto hasta que llegue al extremo llamado Final.
Detalle:
En un principio se compara para saber si tiene algún dato en la Cola, si no es así desplegara “Cola Vacía…”. De otra forma compara si Frente es mayor o igual a Final, de esta forma simplemente hace un Recorrido lineal como los anteriores. De otra forma usar Max como bandera para saber cuando empezar a contar de 0 a Final (Ya que sabemos que el Frente después del nodo Final).
Algoritmo:
Recorrido(Cola, Frente, Final, Max)

Si Frente ≠ Nulo

Si Frente ≤ Final, entonces:

Apuntador <-- Frente

Repetir mientras Apuntador ≤ Final

Imprimir Cola[Apuntador]

Apuntador <-- Apuntador + 1

Fin del ciclo

Si no, si Frente > Final, entonces:

Apuntador <-- Frente

Repetir mientras Apuntador ≠ Final

Si Apuntador > Max, entonces:

Apuntador <-- 0

Imprimir Cola[Apuntador]

Apuntador <-- Apuntador + 1

Fin del ciclo

Si no:

Imprimir "Cola Vacía"

Salir
ama:


Corrida:


Push
Definición:
Push es simplemente el método por el cual va agregando un Dato nuevo a la Cola tomando en cuenta el Tamaño Máximo de Capacidad (Max), el Frente y el Final de la Cola.
Detalle:
Primer nos aseguramos que la Cola no este Llena, para que de esta manera sea capaz de insertar un Elemento nuevo. Si no desplegara Cola Llena. Después compara para determinar las posiciones de Frente y Final y de esta manera poder moverlo con libertad. Ya que determina los valores de Frente y Final, nos Indica que Cola[Final] tomara el valor de Elemento.
Algoritmo:
Push(Cola, Frente, Final, Max, Elemento)

Si Frente = 0 y Final =9, o si Frente = (Final + 1)

Imprimir "Cola Llena" y Salir

Si Frente = Nulo

Frente <-- 0

Final <-- 0

Si no, si Final = Max

Final <-- 0

Si no:

Final <-- Final + 1

Cola[Final] = Elemento

Salir


corrida:


Pop
Definición:
Pop es simplemente el método por el cual va sacando el primer Dato de la Cola (esto se comprueba ya que las Colas son FIFO), para esto toma en cuenta el Frente.
Detalle:
Compara para determinar si la cola esta vacía, de otra forma lo que hace es Imprimir “Eliminando el Dato…”. Después se hacen una series de comparaciones para determinar la nueva posición de Frente, de esa forma el Dato que existía en Frente es Eliminado.
Algoritmo:
Pop(Cola, Frente, Final, Max)

Si Frente ≠ Nulo

Imprimir "Eliminado el Dato..."

Si Frente = Final

Frente = Nulo

Final = Nulo

Si no, si Frente = Max

Frente = 0

Si no:

Frente <-- Frente + 1

Si no:

Imprimir "Cola Vacía"

Salir

diagrama:



corrida:



Búsqueda
Definición:
Este método usa el recorrido para encontrar Elemento y desplegar un mensaje si la búsqueda es exitosa.
Detalle:
El algoritmo usa básicamente la misma estructura del Recorrido, la única diferencia es que compara cada uno de los Datos con Elemento, de esta forma se da cuenta si este Dato existe en la Cola.
Algoritmo:
Busqueda(Cola, Frente, Fin, Max, Elemento)

Si Frente ≠ Nulo

Si Frente ≤ Final, entonces:

Apuntador <-- Frente

Repetir mientras Apuntador ≤ Final

Si Elemento = Cola[Apuntador]

Imprimir "Dato encontrado..." y Salir

Apuntador <-- Apuntador + 1

Fin del ciclo

Si no, si Frente > Final, entonces:

Apuntador <-- Frente

Repetir mientras Apuntador ≠ Final

Si Apuntador > Max, entonces:

Apuntador <-- 0

Si Elemento = Cola[Apuntador]

Imprimir "Dato encontrado..." y Salir

Apuntador <-- Apuntador + 1

Fin del ciclo

Imprimir "Dato no encontrado..."

Si no:

Imprimir "Cola Vacía"

Salir

diagrama:


corrida:

Eliminacion
Definición:
Este método busca un Dato dentro de la cola y lo elimina.
Detalle:
Este Método es la mezcla de todos en uno, Recorrido, Búsqueda, Pop y Push. Debido que a busca el Dato haciendo un Recorrido, y en el proceso copia todos los Datos que no son en un Arreglo Temp, para después meterlos a la Cola original, esto lo hace hasta encontrar el dato deseado que posteriormente lo Elimina.

Diagrama:

corrida:



3.2.5 Recursividad con ayuda de pilas.

Las pilas se usan comúnmente para indicar en que punto se encuentra un programa cuando contiene procedimientos que se llaman a si mismos. Estos procedimientos se conocen como procedimientos recursivos.
La recursividad es una técnica en la que un procedimiento o función se hace llamadas a si mismo en el proceso de realización de sus tareas. La recursividad se puede definir mediante un clásico ejemplo de la función factorial. La recursividad es una técnica de programación muy potente que puede ser usada en lugar de una iteración (Bucles o ciclos). Ello implica una forma diferente de ver las acciones repetitivas permitiendo que un subprograma se llame a si mismo para resolver una operación mas pequeña del programa original.

4!= 4*3*2*1=24

3.2.4 Notación infija y postfija

 La notación infija es la forma natural de escribir expresiones aritméticas por ejemplo (A+B)*C y  A+ (B*C), en esta notación se sitúa el operador entre sus operandos.
 El inconveniente de esta notación es que muchas veces se necesita de paréntesis para indicar el orden de evaluación: A*B/(A+C) <>A*B/A+C (diferente resultado).
 Suponga que queremos evaluar la siguiente expresión aritmética sin paréntesis:
2 ˆ 3   + 5 * 2 ˆ 2 – 12 / 6
Primero evaluamos las potencias para obtener
8 + 5 * 4 – 12 / 6
Entonces evaluamos la multiplicación y división y se obtiene 8 + 20 -2.
Evaluamos la suma y la resta y se obtiene 26 realizándola en 3 niveles de precedencia
 La notación postfija (Polaca inversa) debe su nombre al matemático polaco Jan Lukasiewicz, y en esta notación el símbolo operador se coloca delante de sus operandos. 
 La ventaja de la notación postfija es que no se requieren de paréntesis para su evaluación, además es más utilizada por las computadoras ya que permite una forma muy sencilla y eficiente de evaluar expresiones aritméticas (con pilas).

Infija
Postfija
a/b+c*d-e*f
ab/cd*+ef*-
a*b / (a+c)
ab*ac+/

Conversión de Infija a Postfija a través de pilas.
 Primero hay que saber que en una expresión se tienen operadores y que estos tienen cierta prioridad.
 Operadores

Operador
Símbolo
Prioridad
Paréntesis
( )
Mas alta
Potencia
^
Multiplicación / División
*  /
Suma / Resta
+ -
Mas Baja

En caso de una igualdad en una expresión:
·         Son evaluados de izquierda a derecha (se evalúa primero el que primero aparece)  5*4/2 = (5*4)/2 = 10
·       Cuando aparecen varios operadores de potenciación juntos la expresión se evalúa de derecha a izquierda  2^3^2 = 2^(3^2) = 2^9 = 512.