SlideShare uma empresa Scribd logo
1 de 110
Baixar para ler offline
INDICE
ESTRUCTURA DE DATOS
1. Análisis de algoritmos.………………………………………………………………… 1
2. Manejo de Memoria……………………………………………………………………. 3
3. Estructura de Datos…………………………………………………………………….. 6
3.1 Pilas……………………………………………………………………………………….. 6
3.2 Colas……………………………………………………………………………………… 14
3.3 Listas Enlazadas……………………………………………………………………… 26
3.4 Listas Circulares……………………………………………………………………… 42
3.5 Listas Dobles………………………………………………………………………….. 53
4. Recursividad………………………………………………………………………………… 61
5. Árboles……………………………………………………………………………………….. 63
5.1 Arboles Binarios……………………………………………………………………… 63
5.2 Árboles en Montón………………………………………………………………… 73
6. Ordenamientos Internos………………………………………………………………. 81
7. Ordenamientos Externos……………………………………………………………… 89
8. Búsquedas………………………………………………………………………………….. 94
9. GRAFOS……………………………………………………………………………………... 106
1
ESTRUCTURA DE DATOS
UNIDAD 1: Análisis de Algoritmos
Concepto Complejidad Algoritmos
La resolución práctica de un problema exige por una parte un algoritmo o método de
resolución y por otra un programa o codificación de aquel en un ordenador real.
Ambos componentes tienen su importancia, pero la del algoritmo es absolutamente
esencial, mientras que la codificación puede muchas veces pasar a nivel de anécdota.
A efectos prácticos o ingenieriles, nos deben preocupar los recursos físicos necesarios
para que un programa se ejecute.
Aunque puede haber muchos parámetros, los más usuales son el tiempo de ejecución y la
cantidad de memoria (espacio).
Ocurre con frecuencia que ambos parámetros están fijados por otras razones y se plantea
la pregunta inversa: ¿cuál es el tamaño del mayor problema que puedo resolver en T
segundos y/o con M bytes de memoria?
En lo que sigue nos centramos casi siempre en el parámetro tiempo de ejecución, si bien
las ideas desarrolladas son fácilmente aplicables a otro tipo de recursos.
Para cada problema determinaremos una medida N de su tamaño (por número de datos)
e intentaremos hallar respuestas en función de dicho N.
El concepto exacto que mide N depende de la naturaleza del problema.
Así, para un vector se suele utilizar como N su longitud; para una matriz, el número de
elementos que la componen; para un grafo, puede ser el número de nodos (a veces es
más importante considerar el número de arcos, dependiendo del tipo de problema a
resolver), en un archivo se suele usar el número de registros, etc.
Es imposible dar una regla general, pues cada problema tiene su propia lógica de coste.
Tiempo de Ejecución
Una medida que suele ser útil conocer es el tiempo de ejecución de un programa en
función de N, lo que denominaremos T(N).
Esta función se puede medir físicamente (ejecutando el programa, reloj en mano), o
calcularse sobre el código contando instrucciones a ejecutar y multiplicando por el tiempo
requerido por cada instrucción.
Así, un trozo sencillo de programa como:
S1; for (int i= 0; i < N; i++) S2;
2
Requiere
T(N)= t1 + t2*N
Siendo t1 el tiempo que lleve ejecutar la serie “S1” de sentencias, y t2 el que lleve la serie
“S2”.
Prácticamente todos los programas reales incluyen alguna sentencia condicional,
haciendo que las sentencias efectivamente ejecutadas dependan de los datos concretos
que se le presenten.
Esto hace que más que un valor T(N) debamos hablar de un rango de valores
Tmin(N) ⇐⇐⇐⇐ T(N) ⇐⇐⇐⇐ Tmax(N)
Los extremos son habitualmente conocidos como “caso peor” y “caso mejor”.
Entre ambos se hallara algún “caso promedio” o más frecuente.
Cualquier fórmula T(N) incluye referencias al parámetro N y a una serie de constantes “Ti”
que dependen de factores externos al algoritmo como pueden ser la calidad del código
generado por el compilador y la velocidad de ejecución de instrucciones del ordenador
que lo ejecuta.
Dado que es fácil cambiar de compilador y que la potencia de los ordenadores crece a un
ritmo vertiginoso (en la actualidad, se duplica anualmente), intentaremos analizar los
algoritmos con algún nivel de independencia de estos factores; es decir, buscaremos
estimaciones generales ampliamente válidas.
3
UNIDAD 2: Manejo de Memoria
Memoria 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.
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:
• Los objetos correspondientes a procedimientos o funciones recursivas, ya que en
tiempo de compilación no se sabe el número de variables que serán necesarias.
• Las estructuras dinámicas de datos tales como listas, árboles, etc. ya que el
número de elementos que las forman no es conocido hasta que el programa se
ejecuta.
Las técnicas de asignación de memoria estática son sencillas.
A partir de una posición señalada por un puntero de referencia se aloja el objeto X, y se
avanza el puntero tantos bytes como sean necesarios para almacenar el objeto X.
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.
Dentro de cada registro de activación las variables locales se organizan secuencialmente.
Existe un solo registro de activación para cada procedimiento y por tanto no están
permitidas las llamadas recursivas. El proceso que se sigue cuando un procedimiento p
llama a otra q es el siguiente:
1. p evalúa los parámetros de llamada, en caso de que se trate de expresiones
complejas, usando para ello una zona de memoria temporal para el
almacenamiento intermedio. Por ejemplos, sí la llamada a q es
q((3*5)+(2*2),7) las operaciones previas a la llamada propiamente dicha en
código máquina han de realizarse sobre alguna zona de memoria temporal. (En
algún momento debe haber una zona de memoria que contenga el valor
intermedio 15, y el valor intermedio 4 para sumarlos a continuación). En caso de
utilización de memoria estática ésta zona de temporales puede ser común a todo
el programa, ya que su tamaño puede deducirse en tiempo de compilación.
4
2. q inicializa sus variables y comienza su ejecución.
Dado que las variables están permanentemente en memoria es fácil implementar la
propiedad de que conserven o no su contenido para cada nueva llamada
Memoria Dinámica
¿Qué es la memoria dinámica?
Supongamos que nuestro programa debe manipular estructuras de datos de longitud
desconocida. Un ejemplo simple podría ser el de un programa que lee las líneas de un
archivo y las ordena. Por tanto, deberemos leer un número indeterminado de líneas, y
tras leer la última, ordenarlas. Una manera de manejar ese ``número indeterminado'',
sería declarar una constante MAX_LINEAS, darle un valor vergonzosamente grande, y
declarar un array de tamaño MAX_LINEAS. Esto, obviamente, es muy ineficiente (y feo).
Nuestro programa no sólo quedaría limitado por ese valor máximo, sino que además
gastaría esa enorme cantidad de memoria para procesar hasta el más pequeño de los
ficheros.
La solución consiste en utilizar memoria dinámica. La memoria dinámica es un espacio de
almacenamiento que se solicita en tiempo de ejecución. De esa manera, a medida que el
proceso va necesitando espacio para más líneas, va solicitando más memoria al sistema
operativo para guardarlas. El medio para manejar la memoria que otorga el sistema
operativo, es el puntero, puesto que no podemos saber en tiempo de compilación dónde
nos dará huecos el sistema operativo (en la memoria de nuestro PC).
Memoria Dinámica.
Sobre el tratamiento de memoria, GLib dispone de una serie de instrucciones que
sustituyen a las ya conocidas por todos malloc, free, etc. y, siguiendo con el modo de
llamar a las funciones en GLib, las funciones que sustituyen a las ya mencionadas son
g_malloc y g_free.
Reserva de memoria.
La función g_malloc posibilita la reserva de una zona de memoria, con un número de
bytes que le pasemos como parámetro. Además, también existe una función similar
llamada g_malloc0 que, no sólo reserva una zona de memoria, sino que, además, llena
esa zona de memoria con ceros, lo cual nos puede beneficiar si se necesita un zona de
memoria totalmente limpia.
gpointer g_malloc (gulong numero_de_bytes );
gpointer g_malloc0 (gulong numero_de_bytes );
Existe otro conjunto de funciones que nos permiten reservar memoria de una forma
parecida a cómo se hace en los lenguajes orientados a objetos.
5
Liberación de memoria.
Cuando se hace una reserva de memoria con g_malloc y, en un momento dado, el uso
de esa memoria no tiene sentido, es el momento de liberar esa memoria. Y el sustituto de
free es g_free que, básicamente, funciona igual que la anteriormente mencionada.
void g_free (gpointer memoria_reservada );
Realojamiento de memoria
En determinadas ocasiones, sobre todo cuando se utilizan estructuras de datos dinámicas,
es necesario ajustar el tamaño de una zona de memoria (ya sea para hacerla más grande o
más pequeña). Para eso, GLib ofrece la función g_realloc, que recibe un puntero a
memoria que apunta a una región que es la que será acomodada al nuevo tamaño y
devuelve el puntero a la nueva zona de memoria. El anterior puntero es liberado y no se
debería utilizar más:
gpointer g_realloc (gpointer memoria_reservada , gulong
numero_de_bytes );
Asignación dinámica
El proceso de compactación del punto anterior es una instancia particular del problema de
asignación de memoria dinámica, el cual es el cómo satisfacer una necesidad de tamaño n
con una lista de huecos libres. Existen muchas soluciones para el problema. El conjunto de
huecos es analizado para determinar cuál hueco es el más indicado para asignarse. Las
estrategias más comunes para asignar algún hueco de la tabla son:
Primer ajuste: Consiste en asignar el primer hueco con capacidad suficiente. La
búsqueda puede iniciar ya sea al inicio o al final del conjunto de huecos o en donde
terminó la última búsqueda. La búsqueda termina al encontrar un hueco lo
suficientemente grande.
Mejor ajuste: Busca asignar el espacio más pequeño de los espacios con capacidad
suficiente. La búsqueda se debe de realizar en toda la tabla, a menos que la tabla esté
ordenada por tamaño. Esta estrategia produce el menor desperdicio de memoria posible.
Peor ajuste: Asigna el hueco más grande. Una vez más, se debe de buscar en toda la
tabla de huecos a menos que esté organizada por tamaño. Esta estrategia produce los
huecos de sobra más grandes, los cuales pudieran ser de más uso si llegan procesos de
tamaño mediano que quepan en ellos.
Se ha demostrado mediante simulacros que tanto el primer y el mejor ajuste son mejores
que el peor ajuste en cuanto a minimizar tanto el tiempo del almacenamiento. Ni el
primer o el mejor ajuste es claramente el mejor en términos de uso de espacio, pero por
lo general el primer ajuste es más rápido.
6
UNIDAD 3: ESTRUCTURA DATOS
3.1 PILAS LIFO
Son aquellas que solo tiene 2 operaciones, Push(Inserción) y Pop(Eliminación) la
cual solo se puede efectuar por un extremo llamado Top. Sin Embargo se le pueden aplicar
todas las operaciones al igual que a las listas.
Recorrido
Ya que las pilas son LIFO(Last in - First Out) el Recorrido se hace sacando el
último dato que se insertó hasta que no encuentre ningún otro.
Detalle:
Apuntador toma el Top, después ve si la condición cumple para efectuar un Ciclo mientras
Apuntador sea diferente de Nulo, si cumple lo que hace es que despliega el contenido de
la Pila(Pila[Apuntador]), después Apuntador se le resta 1. Este proceso se repite
hasta que Apuntador sea igual Nulo(Cuando llega a este punto la Pila ya
fue Recorrida).
Algoritmo:
Recorrido(Pila, Top)
Apuntador ←- Top
Repetir mientras Apuntador &ne; Nulo
Imprimir Pila[Apuntador]
Apuntador ←- Apuntador - 1
Fin del ciclo
Salir
Diagrama:
7
Corrida:
Push
Push es simplemente el método por el cual va agregando un Dato nuevo a la Pila
tomando en cuenta la Capacidad Máxima (Max) de almacenar un dato.
Detalle:
Compara en un principio el Top con Max, si la condición no cumple es imposible insertar
más datos a la Pila, de otra forma lo que hace es Incrementar el valor de Top, y copia el
valor de Elemento en Pila[Top]. De esta forma el dato ya está insertado.
Algoritmo:
Push(Pila, Top, Max, Elemento)
Si Top &ne; Max
Top ←- Top + 1
Pila[Top] ←- Elemento
Si no:
Imprimir “Pila Llena”
Salir
Diagrama:
8
Corrida:
Búsqueda
Este método usa el recorrido para encontrar Elemento y desplegar un mensaje si la
búsqueda es exitosa.
Detalle:
El algoritmo compara para determinar si la Pila tiene algún dato, sino simplemente
desplegara Lista Vacía y saldrá. De otra manera hará un Recorrido y comparara con cada
uno de los Datos de la Pila hasta encontrar el dato que desea buscar. Si lo encuentra
desplegara “El Dato fue encontrado” de otra manera “El Dato no se encontró”.
Algoritmo:
Busqueda(Pila, Top, Elemento)
Si Top &ne; Nulo
Apuntador ←- Top
Repetir mientras Apuntador &ne; Nulo
Si Pila[Apuntador] = Elemento
Imprimir “El Dato fue encontrado” y Salir
Apuntador ←- Apuntador - 1
Fin del ciclo
Imprimir “El Dato no se encontró”
Si no:
Imprimir “Pila Vacía”
Salir
9
Diagrama:
Corrida:
Eliminación
Este método busca un Dato dentro de la pila y lo elimina.
Detalle:
El algoritmo compara para determinar si la Pila tiene algún dato, sino simplemente
desplegara Pila Vacía y saldrá. De otra manera hará un Recorrido y comparara con cada
uno de los Datos de la Pila hasta encontrar el dato que desea eliminar, mientras hace esto
copia cada uno de los datos a un arreglo Temp para cuando encuentre el Dato regresar
esos valores a la Pila. Si lo encuentra desplegara “Eliminado el Dato” y le restara 1 a Top,
de otra manera “El Dato no encontrado”.
Algoritmo:
Borrar(Pila, Temp, Top, Elemento)
Si Top &ne; Nulo
10
Apuntador1 ←- Top
Repetir mientras Apuntador1 &ne; Nulo
Si Pila[Apuntador1] = Elemento
Imprimir “Eliminando el Dato…”
Repetir mientras Apuntador2 &ne; Nulo
Pila[Apuntador1]=Temp[Apuntador2]
Fin del ciclo
Top ←- Top - 1 y Salir
Si No:
Temp[Apuntador2] ←- Pila[Apuntador1]
Apuntador1 ←- Apuntador1 - 1
Apuntador2 ←- Apuntador2 + 1
Fin del ciclo
Imprimir “Dato no encontrado”
Si no:
Imprimir “Pila Vacía”
Salir
Diagrama:
Corrida:
11
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <iomanip.h>
#include <iostream.h>
class Alumno
{
private:
int Pila[10],Top,Max;
char Pila1[10][10];
public:
Alumno()
{
int i,j;
char Nulo[2]=" ";
Max=9;
Top=-1;
for(i=1;i<9;i++)
{
Pila[i]=0;
strcpy(Pila1[i],Nulo);
}
}
void
Push(charElem[10])
{
if(Top!=Max)
{
Top++;
strcpy(Pila1[Top],Elem
);
}
else
cout<<"Pila
Llena"<<endl;
}
void Push(int Elem)
{
if(Top!=Max)
{
Top++;
Pila[Top]=Elem;
}
else
cout<<"Pila
Llena"<<endl;
}
void Push(float Elem)
{
if(Top!=Max)
{
Top++;
Pila[Top]=Elem;
}
else
cout<<"Pila
Llena"<<endl;
}
void Push(double Elem)
{
if(Top!=Max)
{
Top++;
Pila[Top]=Elem;
}
else
cout<<"Pila
Llena"<<endl;
}
void Pop(void)
{
if(Top!=-1)
{
cout<<"Sacando el
Dato: "<<Pila[Top];
Top--;
}
else
cout<<"Pila Vacia...
Imposible
Eliminar"<<endl;
}
void Recorrido(void)
{
if(Top!=-1)
int i;
for(i=Top;i!=-1; i--)
cout<<Pila[i] <<endl;
else
cout<<"Pila Vacia...";
}
Void Busqueda(charElem
[10])
{
Int i;
for(i=Top;i!=-1; i--)
if((strcmp(Elem,
Pila1[i]))==0)
{
cout<<"Dato
"<<Pila1[i] <<"
encontrado..." <<endl;
return;
}
cout<<"Dato no
encontrado..." <<endl;
}
Int Elem;
void Busqueda(Elem)
{
Int i;
for(i=Top;i!=-1; i--)
if(Elem==Pila[i])
{
cout<<"Dato "<<Pila[i]
<<" encontrado..."
<<endl;
return;
}
cout<<"Dato no
encontrado..." <<endl;
}
Float Elem;
void Busqueda(Elem)
{
Int i;
for(i=Top;i!=-1; i--)
if(Elem==Pila[i])
{
cout<<"Dato "<<Pila[i]
<<"encontrado..."
<<endl;
return;
}
cout<<"Dato no
encontrado..." <<endl;
}
Double Elem;
void Busqueda(Elem)
{
Int i;
for(i=Top;i!=-1; i--)
if(Elem==Pila[i])
{
cout<<"Dato "<<Pila[i]
<<"encontrado..."
<<endl;
12
return;
}
cout<<"Dato no
encontrado..." <<endl;
}
void Borrar(charElem
[10])
{
char Temp[10][10];
int i=0,j=Top;
if(Top==-1)
{
cout<<"Pila Vacia...
Imposible
Eliminar...";
return;
}
while(j!=-1)
{
if((strcmp(Elem,
Pila1[j]))==0)
{
cout<<"Dato
Eliminado...";
for(i--;i!= -
1;j++,i--)
strcpy(Pila1[j],
Temp[i]);
Top--;
return;
}
else
{
strcpy(Temp[i],
Pila1[j]);
i++;
j--;
}
}
cout<<"Dato no
encontrado...
Imposible
Eliminar...";
return;
}
void Borrar(int Elem)
{
IntTemp[10],i=0,
j=Top;
if(Top==-1)
{
cout<<"Pila Vacia...
Imposible
Eliminar...";
return;
}
while(j!=-1)
{
if(Elem==Pila[j])
{
cout<<"Dato
Eliminado...";
for(i--;i!= -
1;j++,i--)
Pila[j]=Temp[i];
Top--;
return;
}
else
{
Temp[i]=Pila[j];
i++;
j--;
}
}
cout<<"Dato no
encontrado...
Imposible
Eliminar...";
return;
}
Float Elem;
void Borrar(Elem)
{
intTemp[10],i=0,
j=Top;
if(Top==-1)
{
cout<<"Pila Vacia...
Imposible
Eliminar...";
return;
}
while(j!=-1)
{
if(Elem==Pila[j])
{
cout<<"Dato
Eliminado...";
for(i--;i!= -
1;j++,i--)
Pila[j]=Temp[i];
Top--;
return;
}
else
{
Temp[i]=Pila[j];
i++;
j--;
}
}
cout<<"Dato no
encontrado...
Imposible
Eliminar...";
return;
}
Double Elem;
void Borrar(Elem)
{
intTemp[10],i=0,
j=Top;
if(Top==-1)
{
cout<<"Pila Vacia...
Imposible
Eliminar...";
return;
}
while(j!=-1)
{
if(Elem==Pila[j])
{
cout<<"Dato
Eliminado...";
for(i--;i!= -
1;j++,i--)
Pila[j]=Temp[i];
Top--;
return;
}
else
{
Temp[i]=Pila[j];
i++;
j--;
}
}
13
cout<<"Dato no
encontrado...
Imposible
Eliminar...";
return;
}
}tec;
main()
{
int res,op=0;
while(op!=6)
{
clrscr();
cout<<"n1)
Recorridon2)
Busquedan3) Pushn4)
Popn5) Eliminar un
Daton6) Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas
hacer?: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido();
break;
case 2:
cout<<"Que Numero
deseas buscar?"<<endl;
cin>>res;
tec.Busqueda(res);
break;
case 3:
cout<<"Que Numero
quieres
Insertar?"<<endl;
cin>>res;
tec.Push(res);
break;
case 4:
tec.Pop();
break;
case 5:
cout<<"Que Numero
deseas
eliminar?"<<endl;
cin>>res;
tec.Borrar(res);
break;
case 6:
cout<<"Salida...";
break;
default:
cout<<"Opcion
Erronea"<<endl;
break;
}
getch();
}
}
14
3.2 Colas FIFO
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
Ya que las colas son FIFO(First in - First Out) el Recorrido se hace sacando el
primer dato que se insertó 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 cuándo 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
15
Diagrama:
Corrida:
Push
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 esté 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.
16
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
Diagrama:
Corrida:
17
Pop
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 está 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:
18
Corrida:
Búsqueda
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
19
Diagrama:
Corrida:
Eliminació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.
20
Diagrama:
Corrida:
21
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <iomanip.h>
#include <iostream.h>
class Alumno
{
private:
intCola[10],Frente,Fin
al,Max;
char Cola1[10][10];
public:
Alumno()
{
int i,j;
char Nulo[2]=" ";
Frente=-1;
Final=-1;
Max=9;
for(i=1;i<9;i++)
{
Cola[i]=0;
strcpy(Cola1[i],Nulo);
}
}
void
Push(charElem[10])
{
if((Frente==0&&Final==
9)||(Frente==(Final+1)
))
{
cout<<"Cola
Llena"<<endl;
return;
}
if(Frente==-1)
{
Frente=0;
Final=0;
}
else if(Final==Max)
Final=0;
else
Final++;
strcpy(Cola1[Final],El
em);
}
void Push(int Elem)
{
if((Frente==0&&Final==
9)||(Frente==(Final+1)
))
{
cout<<"Cola
Llena"<<endl;
return;
}
if(Frente==-1)
{
Frente=0;
Final=0;
}
else if(Final==Max)
Final=0;
else
Final++;
Cola[Final]=Elem;
}
void Push(float Elem)
{
if((Frente==0&&Final==
9)||(Frente==(Final+1)
))
{
cout<<"Cola
Llena"<<endl;
return;
}
if(Frente==-1)
{
Frente=0;
Final=0;
}
else if(Final==Max)
Final=0;
else
Final++;
Cola[Final]=Elem;
}
void Push(double Elem)
{
if((Frente==0&&Final==
9)||(Frente==(Final+1)
))
{
cout<<"Cola
Llena"<<endl;
return;
}
if(Frente==-1)
{
Frente=0;
Final=0;
}
else if(Final==Max)
Final=0;
else
Final++;
Cola[Final]=Elem;
}
void Pop(void)
{
if(Frente!=-1)
{
cout<<"Elmininado el
Dato: "<<Cola[Frente];
if(Frente==Final)
{
Frente=-1;
Final=-1;
}
else if(Frente==Max)
Frente=0;
else
Frente++;
}
else
cout<<"Cola Vacia...
Imposible
Eliminar"<<endl;
}
void Recorrido(void)
{
int i;
if(Frente!=-1)
{
if(Frente<=Final)
for(i=Frente;i<=Final;
i++)
cout<<Cola[i]<<endl;
else if(Frente>Final)
for(i=Frente;i!=Final;
i++)
{
if(i>Max)
22
i=0;
cout<<Cola[i]<<endl;
}
}
else
cout<<"Cola Vacia...";
}
void Busqueda(char
Elem[10])
{
int i;
if(Frente!=-1)
{
if(Frente<=Final)
for(i=Frente;i<=Final;
i++)
if((strcmp(Elem,Cola1[
i]))==0)
{
cout<<"Dato
"<<Cola1[i]<<"
encontrado..."<<endl;
return;
}
else if(Frente>Final)
for(i=Frente;i!=Final;
i++)
{
if(i>Max)
i=0;
if((strcmp(Elem,Cola1[
i]))==0)
{
cout<<"Dato
"<<Cola1[i]<<"
encontrado..."<<endl;
return;
}
}
}
else
cout<<"Dato no
encontrado...";
}
void Busqueda(int
Elem)
{
int i;
if(Frente!=-1)
{
if(Frente<=Final)
for(i=Frente;i<=Final;
i++)
if(Elem==Cola[i])
{
cout<<"Dato
"<<Cola[i]<<"
encontrado..."<<endl;
return;
}
else if(Frente>Final)
for(i=Frente;i!=Final;
i++)
{
if(i>Max)
i=0;
if(Elem==Cola[i])
{
cout<<"Dato
"<<Cola[i]<<"
encontrado..."<<endl;
return;
}
}
}
else
cout<<"Dato no
encontrado...";
}
void Busqueda(float
Elem)
{
int i;
if(Frente!=-1)
{
if(Frente<=Final)
for(i=Frente;i<=Final;
i++)
if(Elem==Cola[i])
{
cout<<"Dato
"<<Cola[i]<<"
encontrado..."<<endl;
return;
}
else if(Frente>Final)
for(i=Frente;i!=Final;
i++)
{
if(i>Max)
i=0;
if(Elem==Cola[i])
{
cout<<"Dato
"<<Cola[i]<<"
encontrado..."<<endl;
return;
}
}
}
else
cout<<"Dato no
encontrado...";
}
void Busqueda(double
Elem)
{
int i;
if(Frente!=-1)
{
if(Frente<=Final)
for(i=Frente;i<=Final;
i++)
if(Elem==Cola[i])
{
cout<<"Dato
"<<Cola[i]<<"
encontrado..."<<endl;
return;
}
else if(Frente>Final)
for(i=Frente;i!=Final;
i++)
{
if(i>Max)
i=0;
if(Elem==Cola[i])
{
cout<<"Dato
"<<Cola[i]<<"
23
encontrado..."<<endl;
return;
}
}
}
else
cout<<"Dato no
encontrado...";
}
void Borrar(char
Elem[10])
{
char Temp[10][10];
int i,j;
if(Frente!=-1)
{
if(Frente<=Final)
for(j=0,i=Frente;i<=Fi
nal;i++,j++)
{
if((strcmp(Elem,Cola1[
i]))==0)
{
cout<<"Eliminado el
Dato
"<<Cola1[i]<<endl;
if(Frente==Final)
{
Frente=-1;
Final=-1;
return;
}
else if(Frente==Max)
Frente=0;
else
Frente++;
for(j--,i=Frente;j!=-
1;i++,j--)
strcpy(Cola1[i],Temp[j
]);
return;
}
strcpy(Temp[j],Cola1[i
]);
}
else if(Frente>Final)
for(j=0,i=Frente;i!=Fi
nal;i++,j++)
{
if(i>Max)
i=0;
if((strcmp(Elem,Cola1[
i]))==0)
{
cout<<"Eliminado el
Dato
"<<Cola1[i]<<endl;
if(Frente==Max)
Frente=0;
else
Frente++;
for(j--,i=Frente;j!=-
1;i++,j--)
{
if(i>Max)
i=0;
strcpy(Cola1[i],Temp[j
]);
}
return;
}
strcpy(Temp[j],Cola1[i
]);
}
cout<<"Dato no
Encontrado...";
}
else
cout<<"Cola Vacia...
Imposible
Eliminar...";
}
void Borrar(int Elem)
{
int Temp[10],i,j;
if(Frente!=-1)
{
if(Frente<=Final)
for(j=0,i=Frente;i<=Fi
nal;i++,j++)
{
if(Elem==Cola[i])
{
cout<<"Eliminado el
Dato "<<Cola[i]<<endl;
if(Frente==Final)
{
Frente=-1;
Final=-1;
return;
}
else if(Frente==Max)
Frente=0;
else
Frente++;
for(j--,i=Frente;j!=-
1;i++,j--)
Cola[i]=Temp[j];
return;
}
Temp[j]=Cola[i];
}
else if(Frente>Final)
for(j=0,i=Frente;i!=Fi
nal;i++,j++)
{
if(i>Max)
i=0;
if(Elem==Cola[i])
{
cout<<"Eliminado el
Dato "<<Cola[i]<<endl;
if(Frente==Max)
Frente=0;
else
Frente++;
for(j--,i=Frente;j!=-
1;i++,j--)
{
if(i>Max)
i=0;
Cola[i]=Temp[j];
}
return;
}
Temp[j]=Cola[i];
}
cout<<"Dato no
Encontrado...";
}
24
else
cout<<"Cola Vacia...
Imposible
Eliminar...";
}
void Borrar(float
Elem)
{
int Temp[10],i,j;
if(Frente!=-1)
{
if(Frente<=Final)
for(j=0,i=Frente;i<=Fi
nal;i++,j++)
{
if(Elem==Cola[i])
{
cout<<"Eliminado el
Dato "<<Cola[i]<<endl;
if(Frente==Final)
{
Frente=-1;
Final=-1;
return;
}
else if(Frente==Max)
Frente=0;
else
Frente++;
for(j--,i=Frente;j!=-
1;i++,j--)
Cola[i]=Temp[j];
return;
}
Temp[j]=Cola[i];
}
else if(Frente>Final)
for(j=0,i=Frente;i!=Fi
nal;i++,j++)
{
if(i>Max)
i=0;
if(Elem==Cola[i])
{
cout<<"Eliminado el
Dato "<<Cola[i]<<endl;
if(Frente==Max)
Frente=0;
else
Frente++;
for(j--,i=Frente;j!=-
1;i++,j--)
{
if(i>Max)
i=0;
Cola[i]=Temp[j];
}
return;
}
Temp[j]=Cola[i];
}
cout<<"Dato no
Encontrado...";
}
else
cout<<"Cola Vacia...
Imposible
Eliminar...";
}
void Borrar(double
Elem)
{
int Temp[10],i,j;
if(Frente!=-1)
{
if(Frente<=Final)
for(j=0,i=Frente;i<=Fi
nal;i++,j++)
{
if(Elem==Cola[i])
{
cout<<"Eliminado el
Dato "<<Cola[i]<<endl;
if(Frente==Final)
{
Frente=-1;
Final=-1;
return;
}
else if(Frente==Max)
Frente=0;
else
Frente++;
for(j--,i=Frente;j!=-
1;i++,j--)
Cola[i]=Temp[j];
return;
}
Temp[j]=Cola[i];
}
else if(Frente>Final)
for(j=0,i=Frente;i!=Fi
nal;i++,j++)
{
if(i>Max)
i=0;
if(Elem==Cola[i])
{
cout<<"Eliminado el
Dato "<<Cola[i]<<endl;
if(Frente==Max)
Frente=0;
else
Frente++;
for(j--,i=Frente;j!=-
1;i++,j--)
{
if(i>Max)
i=0;
Cola[i]=Temp[j];
}
return;
}
Temp[j]=Cola[i];
}
cout<<"Dato no
Encontrado...";
}
else
cout<<"Cola Vacia...
Imposible
Eliminar...";
}
}tec;
main()
{
int res,op=0;
while(op!=6)
{
clrscr();
cout<<"n1)
Recorridon2)
25
Busquedan3) Pushn4)
Popn5) Eliminar un
Daton6) Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas
hacer?: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido();
break;
case 2:
cout<<"Que Numero
deseas buscar?"<<endl;
cin>>res;
tec.Busqueda(res);
break;
case 3:
cout<<"Que Numero
quieres
Insertar?"<<endl;
cin>>res;
tec.Push(res);
break;
case 4:
tec.Pop();
break;
case 5:
cout<<"Que Numero
deseas
eliminar?"<<endl;
cin>>res;
tec.Borrar(res);
break;
case 6:
cout<<"Salida...";
break;
default:
cout<<"Opcion
Erronea"<<endl;
break;
}
getch();
}
}
26
3.3 Listas Enlazadas
Recorrido
Recorrido simplemente despliega los datos almacenados en el arreglo Info, con ayuda de
un segundo arreglo llamado Índice el cual guarda el orden en el que encuentran enlazados
cada uno de los datos.
Explicación:
Apuntador toma el valor de Inicio, después ve si la condición cumple para efectuar un
Ciclo mientras Apuntador sea diferente de 0, si cumple lo que hace es que despliega la
Info[Apuntador], después Apuntador toma el valor de Indice[Apuntador] (El cual
nos indica el siguiente nodo que sigue en la lista) y hace esto hasta que Apuntador sea
igual a 0 (Cuando llega a este punto a llegado al fin de la Lista Enlazada).
Algoritmo:
Recorrido(Inicio, Info, Indice)
Apuntador ←- Inicio
Repetir mientras Apuntador ≠ Nill
Imprimir Info[Apuntador]
Apuntador ←- Indice[Apuntador]
Fin del ciclo
Salir
Diagrama:
27
Programa:
#include <conio.h>
#include
<iostream.h>
void
Recorrido(char
Info[8][2],int
Indice[8],int
Inicio,int Disp);
void main()
{
char
Info[8][2]={{"G"},
{"I"},{"
"},{"T"},{"O"},{"A
"},
{" "},{"T"}};
int
Indice[8]={5,7,6,1
,-999,3,-999,4};
int
Inicio=0,Disp=2;
cout<<"El
Recorrido es:n";
Recorrido(Info,Ind
ice,Inicio,Disp);
getch();
}
void
Recorrido(char
Info[8][2],int
Indice[8],int
Inicio,int Disp)
{
int
Apuntador=Inicio;
while(Apuntador!=-
999)
{
cout<<Info[Apuntad
or];
Apuntador=Indice[A
puntador];
}
}
Corrida:
Búsqueda
La Búsqueda su objetivo es encontrar un dato en el arreglo Info, si lo encuentra lo
desplegara en la pantalla, si no lo encuentra no desplegara nada ya que el dato no se
encuentra en el arreglo Info.
28
Explicación:
Apuntador toma el valor de Inicio, después ve si la condición cumple para efectuar un
Ciclo mientras Apuntador sea diferente de 0, si cumple lo que hace a continuación es la
comparación de Elemento (El dato que vamos a buscar) con Info[Apuntador], cuando
lo encuentre lo despliega y sale del método. Si no, regresa el valor de Apuntador para así
saber que no se encontró el dato.
Algoritmo:
Recorrido(Inicio, Info, Indice, Elemento)
Apuntador ←- Inicio
Repetir mientras Apuntador ≠ Nill
Si Elemento = Info[Apuntador] entonces:
Imprimir Info[Apuntador]
Regresa Apuntador
Apuntador ←- Indice[Apuntador]
Fin del ciclo
Regresar Apuntador
Diagrama:
29
Programa:
#include <conio.h>
#include
<iostream.h>
int Busqueda(int
Info[8],int
Indice[8],int
Inicio,int
Disp,int
Elemento);
void main()
{
int
Info[8]={12,10,0,9
,5,3,0,20};
int
Indice[8]={5,7,6,1
,-999,3,-999,4};
int
Inicio=0,Disp=2,El
emento,Res;
cout<<"Que Numero
deseas buscar?";
cin>>Elemento;
Res=Busqueda(Info,
Indice,Inicio,Disp
,Elemento);
if(Res==-999)
cout<<"Dato No
Encontrado...";
getch();
}
int Busqueda(int
Info[8],int
Indice[8],int
Inicio,int
Disp,int Elemento)
{
int
Apuntador=Inicio;
while(Apuntador!=-
999)
{
if(Elemento==Info[
Apuntador])
{
cout<<"Numero
"<<Info[Apuntador]
<<"
encontrado...";
return Apuntador;
}
Apuntador=Indice[A
puntador];
}
return Apuntador;
}
Corrida:
30
Inserción al Principio
La Inserción al Principio básicamente busca si existe algún lugar disponible en el arreglo
Info y lo agrega como primer Nodo si es que es posible.
Explicación:
Hace una comparación para ver si es posible insertar otro Elemento al arreglo Info, para
esto checa si Disp es Diferente de Nulo. Si no cumple con la condición se desplegar
“Sobre Carga” ya que no se puede insertar un Nuevo Elemento. Si es cierto Apuntador
toma el valor de Inicio, Disp cambia a Indice[Disp] ya que el primer Disp tomara el
valor del Nuevo Elemento, después de esto solo copia la información de Elemento al
arreglo Info en la posición que guarda Apuntador, Indice[Apuntador] toma el valor
de Inicio y finalmente Inicio toma el valor de Apuntador.
Algoritmo:
InsPr(Inicio, Disp, Info, Indice, Elemento)
Si Disp ≠ Nill entonces:
Apuntador ←- Disp
Disp ←- Indice[Disp]
Info[Apuntador] ←- Elemento
Indice[Apuntador] ←- Inicio
Inicio ←- Apuntador
Si no:
Imprimir “Sobre Carga”
Salir
Diagrama:
31
Programa:
#include <conio.h>
#include
<iostream.h>
void Recorrido(int
Info[8],int
Indice[8],int
Inicio,int Disp);
void InsPr(int
Info[8],int
Indice[8],int
Inicio,int
Disp,int
Elemento);
void main()
{
int
Info[8]={12,10,0,9
,5,3,0,20};
int
Indice[8]={5,7,6,1
,-999,3,-999,4};
int
Inicio=0,Disp=2,El
emento,Res;
cout<<"Lista
Originaln";
Recorrido(Info,Ind
ice,Inicio,Disp);
cout<<"Que Numero
deseas Insertar?";
cin>>Elemento;
InsPr(Info,Indice,
Inicio,Disp,Elemen
to);
getch();
}
void Recorrido(int
Info[8],int
Indice[8],int
Inicio,int Disp)
{
int
Apuntador=Inicio;
while(Apuntador!=-
999)
{
cout<<Info[Apuntad
or]<<endl;
Apuntador=Indice[A
puntador];
}
}
void InsPr(int
Info[8],int
Indice[8],int
Inicio,int
Disp,int Elemento)
{
if(Disp!=-999)
{
int
Apuntador=Disp;
Disp=Indice[Disp];
Info[Apuntador]=El
emento;
Indice[Apuntador]=
Inicio;
Inicio=Apuntador;
Recorrido(Info,Ind
ice,Inicio,Disp);
}
else
cout<<"Overflow...
";
}
32
CORRIDA:
Inserción después de Un Nodo Determinado
La Inserción después de un Nodo Determinado básicamente hace lo mismo que la
inserción al principio, la única diferencia es que este recibe la posición del nodo en la que
será Insertada. Este Algoritmo se usa para Inserción Ordenada que más adelante
explicaremos.
Explicación:
Primero confirma que sea posible insertar el Dato, si no es posible solo desplegara “Sobre
Carga”. Si es posible insertar un dato nuevo lo posiciona en la primer posición Disponible
en el arreglo Info, después compara la Nueva Posición (Npos) que le mandamos con
Nill si cumple la condición el dato es insertado en la primer posición, de otra forma se
posicionara en la posición que guarde Npos.
Algoritmo:
InsNd(Inicio, Disp, Info, Indice, Elemento, Npos)
Si Disp ≠ Nill entonces:
Apuntador ←- Disp
Disp ←- Indice[Disp]
Info [Apuntador] ←- Elemento
Si Npos = Nill entonces:
Indice[Apuntador] ←- Inicio
Inicio ←- Apuntador
Si no:
Indice[Apuntador] ←- Indice[Npos]
Indice[Npos] ←- Apuntador
Si no:
Imprimir “Sobre Carga”
Salir
33
Inserción Ordenada
La Inserción Ordenada busca la posición en donde será Insertado el Elemento y la posición
anterior donde será Insertado, después de encontrar la posición en la que será Insertado
el Elemento nos regresa ese valor y lo mandamos al método de la Inserción después de un
Nodo.
Explicación:
En esta ocasión usaremos dos variables para determinar la posición deseada, comparamos
si Inicio es igual a Nill ó si Elemento es menor al dato que se encuentra en
Info[Inicio], si alguna de las dos cumple regresamos Nill, de esta manera Indicamos
que el Elemento será el primero de todo el Arreglo Info, si no es así Temp tomara el valor
de Inicio y Temp2 de la posición que le sigue a Inicio. Hace un ciclo hasta encontrar la
posición en donde se insertara el Nuevo Elemento y va moviéndose de posición con las
variables Temp y Temp2 para así determinar qué posición debe de regresar.
Algoritmo:
InsOrd(Inicio, Info, Indice, Elemento)
Si Inicio = Nill ó Elemento < Info[Inicio] entonces:
Regresar Nill
Temp ←- Inicio
Temp2 ←- Indice[Inicio]
Repetir mientras Temp2 ≠ Nill
Si Elemento < Info[Temp2]
Regresar Temp
Temp ←- Temp2
Temp2 ←- Indice[Temp2]
Regresar Temp
Diagrama:
34
Programa:
#include <conio.h>
#include
<iostream.h>
int InsOrd(int
Info[8],int
Indice[8],int
Inicio,int
Elemento);
void Recorrido(int
Info[8],int
Indice[8],int
Inicio,int Disp);
void InsNd(int
Info[8],int
Indice[8],int
Inicio,int Disp,
int Elemento, int
Npos);
void main()
{
int
Info[8]={12,10,0,9
,5,3,0,20};
int
Indice[8]={5,7,6,1
,-999,3,-999,4};
int
Inicio=0,Disp=2,El
emento,Res;
cout<<"Lista
Originaln";
Recorrido(Info,Ind
ice,Inicio,Disp);
cout<<"Que Numero
deseas Insertar?";
cin>>Elemento;
Res=InsOrd(Info,In
dice,Inicio,Elemen
to);
InsNd(Info,Indice,
Inicio,Disp,Elemen
to,Res);
getch();
}
void Recorrido(int
Info[8],int
Indice[8],int
Inicio,int Disp)
{
int
Apuntador=Inicio;
while(Apuntador!=-
999)
{
cout<<Info[Apuntad
or]<<endl;
Apuntador=Indice[A
puntador];
}
}
void InsNd(int
Info[8],int
Indice[8],int
Inicio,int Disp,
int Elemento, int
Npos)
{
if(Disp!=-999)
{
int
Apuntador=Disp;
Disp=Indice[Disp];
Info[Apuntador]=El
emento;
if(Npos==-999)
{
Indice[Apuntador]=
Inicio;
Inicio=Apuntador;
}
else
{
Indice[Apuntador]=
Indice[Npos];
Indice[Npos]=Apunt
ador;
}
Recorrido(Info,Ind
ice,Inicio,Disp);
}
else
cout<<"Overflow...
";
}
int InsOrd(int
Info[8],int
Indice[8],int
Inicio,int
Elemento)
{
int Temp=-
999,Temp2;
if(Inicio==Temp||E
lemento<Info[Inici
o])
return Temp;
Temp=Inicio;
Temp2=Indice[Inici
o];
while(Temp2!=-999)
{
if(Elemento<Info[T
emp2])
return Temp;
Temp=Temp2;
Temp2=Indice[Temp2
];
}
return Temp;
}
35
CORRIDA:
Eliminación por Búsqueda
La Eliminación simplemente cambia los nodos para que el dato que se desea eliminar sea
el primer disponible, de esta forma ya no estará en el Arreglo de Info.
Explicación:
Lo primero que hace es ver si existe algún dato en la lista para eliminar, si Inicio es igual a
Nill entonces solo desplegara “Imposible Eliminar”. De otra formas cambiar de Posición en
Posición hasta encontrar el Elemento que sea desea Eliminar con ayudar de dos variables
que guardan la Posición actual y la anterior en donde se encuentre el dato. Ya que lo
encuentra cambia ese dato como la primera posición Disponible y lo apunta al siguiente
nodo disponible. Si no encuentra el dato simplemente desplegara “Dato no encontrado”
Algoritmo:
EliBusq(Inicio, Info, Indice, Elemento)
Temp ←- Inicio
Si Temp = Nill
Imprimir “Lista Vacia… Imposible Eliminar” y Retornar
Repetir mientras Temp ≠ Nill
Si Elemento = Info[Temp] entonces:
Si Temp = Inicio entonces:
Inicio ←- Indice[Inicio]
Si no:
Indice[Temp2] ←- Indice[Temp]
Indice[Temp] ß Disp
Disp ←- Temp
Recorrido(Inicio, Info, Indice) y Retornar
Si no:
Temp2 ←- Temp
Temp ←- Indice[Temp]
Imprimir “Dato no encontrado… Imposible Eliminar” y Retornar
36
Diagrama
Programa:
#include <conio.h>
#include
<iostream.h>
void Recorrido(int
Info[8],int
Indice[8],int
Inicio,int Disp);
void EliBusq(int
Info[8],int
Indice[8],int
Inicio,int
Disp,int
Elemento);
void main()
{
int
Info[8]={12,10,0,9
,5,3,0,20};
int
Indice[8]={5,7,6,1
,-999,3,-999,4};
int
Inicio=0,Disp=2,El
emento,Res;
cout<<"Lista
Originaln";
Recorrido(Info,Ind
ice,Inicio,Disp);
cout<<"Que Numero
deseas Eliminar?";
cin>>Elemento;
EliBusq(Info,Indic
e,Inicio,Disp,Elem
ento);
getch();
}
void Recorrido(int
Info[8],int
Indice[8],int
Inicio,int Disp)
{
int
Apuntador=Inicio;
while(Apuntador!=-
999)
{
cout<<Info[Apuntad
or]<<endl;
Apuntador=Indice[A
puntador];
}
}
void EliBusq(int
Info[8],int
Indice[8],int
Inicio,int
Disp,int Elemento)
{
int
Temp=Inicio,Temp2;
if(Temp==-999)
{
cout<<"Lista
Vacia... Imposible
Eliminar";
return;
}
while(Temp!=-999)
{
if(Elemento==Info[
37
Temp])
{
if(Temp==Inicio)
Inicio=Indice[Inic
io];
else
Indice[Temp2]=Indi
ce[Temp];
Indice[Temp]=Disp;
Disp=Temp;
Recorrido(Info,Ind
ice,Inicio,Disp);
return;
}
else
{
Temp2=Temp;
Temp=Indice[Temp];
}
}
cout<<"Dato no
encontrado...
Imposible
Eliminar";
return;
}
CORRIDA:
38
#include <stdio.h>
#include <conio.h>
#include <iomanip.h>
#include <iostream.h>
class Alumno
{
private:
char Nombre[10][30];
int
N_control[10],Edad[10]
,Indice1[10],Indice2[1
0],Inicio,Fin,Disp;
public:
//Constructor
Alumno()
{
int i,j;
Inicio=0;
Fin=0;
Disp=1;
Indice1[Inicio]=-999;
Indice2[Fin]=-999;
for(i=1;j=2;i<9;i++;
j++)
Indice1[i]=j;
Indice1[9]=-999;
}
//Funcion de Recorrido
void Recorrido(int op)
{
int i=0,Temp;
if(op==1)
{
Temp=Indice1[Inicio];
if(Temp!=-999)
{
cout<<"Numero de
Control"<<setw(19)<<"N
ombre del
Alumno"<<setw(5)<<"Eda
d"<<endl;
while(Temp!=-999)
{
if(i==(int(Edad[Inicio
]/2)))
{
N_control[Inicio]=N
control[i];
strcpy(Nombre[Inicio],
Nombre[i]);
}
cout<<setw(9)<<N_contr
ol[Temp]<<setw(22)<<
Nombre[Temp]<<setw(9)
<<Edad[Temp]<<endl;
Temp=Indice1[Temp];
i++;
}
}
else
cout<<"Lista
Vacia...";
}
if(op==2)
{
Temp=Fin;
if(Edad[Inicio]!=0)
{
cout<<"Numero de
Control"<<setw(19)<<"N
ombre del
Alumno"<<setw(5)<<"Eda
d"<<endl;
while(Temp!=-
999&&i<Edad[Inicio])
{
if(i==(int(Edad[Inicio
]/2)))
{
N_control[Inicio]=N_co
ntrol[i];
strcpy(Nombre[Inicio],
Nombre[i]);
}
cout<<setw(9)<<N_contr
ol[Temp]<<setw(22)<<No
mbre[Temp]<<setw(9)<<E
dad[Temp]<<endl;
Temp=Indice2[Temp];
i++;
}
}
else
cout<<"Lista
Vacia...";
}
}
//Funcion de Busqueda
Sobrecargada para un
Dato Entero
int Busqueda(int Elem)
{
if(Elem<N_control[
Inicio])
{
int
Temp=Indice1[Inicio];
while(Temp!=-999)
{
if(Elem==N_control[
Temp])
{
gotoxy(1,10);
cout<<"Numero de
Control"<<setw(19)<<"N
ombre del
Alumno"<<setw(5)<<"Eda
d"<<endl;
cout<<setw(9)<<N_contr
ol[Temp]<<setw(22)<<No
mbre[Temp]<<setw(9)<<E
dad[Temp]<<endl;
return Temp;
}
else
Temp=Indice1[Temp];
}
}
else
{
int Temp=Fin;
while(Temp!=-999)
{
if(Elem==N_control[
Temp])
{
gotoxy(1,10);
cout<<"Numero de
Control"<<setw(19)<<
"Nombre del
Alumno"<<setw(5)<<"Eda
d"<<endl;
cout<<setw(9)<<N_contr
ol[Temp]<<setw(22)<<
Nombre[Temp]<<setw(9)
<<Edad[Temp]<<endl;
39
return Temp;
}
else
Temp=Indice2[Temp];
}
}
return -999;
}
//Funcion de Busqueda
Sobrecargada para una
Cadena de Caracteres
int Busqueda(char
Elem[30])
{
if((strcmp(Elem,Nombre
[Inicio]))<0)
{
int
Temp=Indice1[Inicio];
while(Temp!=-999)
{
if((strcmp(Elem,Nombre
[Temp]))==0)
{
gotoxy(1,10);
cout<<"Numero de
Control"<<setw(19)<<
"Nombre del
Alumno"<<setw(5)
<<"Edad"<<endl;
cout<<setw(9)
<<N_control[Temp]
<<setw(22)<<Nombre[
Temp]<<setw(9)<<Edad[
Temp]<<endl;
return Temp;
}
else
Temp=Indice1[Temp];
}
}
else
{
int Temp=Fin;
while(Temp!=-999)
{
if((strcmp(Elem,Nombre
[Temp]))==0)
{
gotoxy(1,10);
cout<<"Numero de
Control"<<setw(19)<<
"Nombre del
Alumno"<<setw(5)
<<"Edad"<<endl;
cout<<setw(9)
<<N_control[Temp]
<<setw(22)<<Nombre[
Temp]<<setw(9)<<Edad[
Temp]<<endl;
return Temp;
}
else
Temp=Indice2[Temp];
}
}
return -999;
}
//Funcion Sobrecargada
de Orden para un Dato
Entero
int Enca(int E_nc)
{
int
Temp=Indice1[Inicio],
Temp2;
if(Temp==-
999||E_nc<N_control[
Temp])
return -999;
Temp2=Indice1[Indice1[
Inicio]];
while(Temp2!=-999)
{
if(E_nc<N_control[
Temp2])
return Temp;
Temp=Temp2;
Temp2=Indice1[Temp2];
}
return Temp;
}
//Funcion Sobrecargada
de Orden para una
Cadena de Caracteres
int Enca(char
E_nom[30])
{
int
Temp=Indice1[Inicio],T
emp2;
if(Temp==-999)
return -999;
if((strcmp(E_nom,Nombr
[Temp]))<0)
return Temp;
Temp2=Indice1[Indice1[
Inicio]];
while(Temp2!=-999)
{
if((strcmp(
E_nom,Nombre[Temp2]))
<0)
return Temp;
Temp=Temp2;
Temp2=Indice1[Temp2];
}
return Temp;
}
//Funcion para la
Insercion en un Lugar
Determinado
void InsLug(char
E_nom[30],int E_nc,int
E_edad,int Npos)
{
if(Disp!=-999)
{
Edad[Inicio]++;
int Temp=Disp;
Disp=Indice1[Disp];
strcpy(Nombre[Temp],
E_nom);
N_control[Temp]=E_nc;
Edad[Temp]=E_edad;
if(Npos==-999)
{
Indice1[Temp]=Indice1[
Inicio];
if(Indice2[Fin]==-999)
{
Indice2[Temp]=Fin;
Fin=Temp;
}
else
40
{
Indice2[Temp]=Indice1[
Inicio];
Indice2[Indice1[Inicio
]]=Temp;
}
Indice1[Inicio]=Temp;
}
else
{
Indice1[Temp]=Indice1[
Npos];
if(Fin==Npos)
{
Indice2[Temp]=Fin;
Fin=Temp;
}
else
{
Indice2[Temp]=Npos;
Indice2[Indice1[Npos]]
=Temp;
}
Indice1[Npos]=Temp;
}
}
else
cout<<"Overflow..."<<
endl;
}
//Funcion Sobrecargada
para Borrar un Dato
Entero
void Borrar(int Elem)
{
int
Temp2,Temp=Indice1[
Inicio];
if(Temp==-999)
{
cout<<"Lista Vacia...
Imposible Eliminar";
return;
}
while(Temp!=-999)
{
if(Elem==N_control[
Temp])
{
Edad[Inicio]--;
if(Temp==Indice1[
Inicio])
{
Indice1[Inicio]=Indice
1[Indice1[Inicio]];
Indice2[Indice1[
Inicio]]=Inicio;
}
else if(Temp==Fin)
{
Indice1[Temp2]=Indice1
[Temp];
Fin=Indice2[Fin];
}
else
{
Indice1[Temp2]=Indice1
[Temp];
Indice2[Indice1[
Temp2]]=Temp2;
}
Indice1[Temp]=Disp;
Disp=Temp;
return;
}
else
{
Temp2=Temp;
Temp=Indice1[Temp];
}
}
cout<<"Dato no
encontrado...
Imposible Eliminar";
return;
}
//Funcion Sobrecargada
para Borrar una Cadena
de Caracteres
void Borrar(char
Elem[30])
{
int
Temp2,Temp=Indice1[
Inicio];
if(Temp==Inicio)
{
cout<<"Lista Vacia...
Imposible Eliminar";
return;
}
while(Temp!=Inicio)
{
if((strcmp(Elem,Nombre
[Temp]))==0)
{
Edad[Inicio]--;
if(Temp==Indice1[Inici
o])
{
Indice1[Inicio]=Indice
1[Indice1[Inicio]];
Indice2[Indice1[
Inicio]]=Inicio;
}
else if(Temp==Fin)
{
Indice1[Temp2]=Indice1
[Temp];
Fin=Indice2[Fin];
}
else
{
Indice1[Temp2]=Indice1
[Temp];
Indice2[Indice1[
Temp2]]=Temp2;
}
Indice1[Temp]=Disp;
Disp=Temp;
return;
}
else
{
Temp2=Temp;
Temp=Indice1[Temp];
}
}
cout<<"Dato no
encontrado...
Imposible Eliminar";
return;
}
}tec;
main()
{
int op=0,res;
char inom[30];
int in_c,iedad;
41
while(op!=6)
{
clrscr();
cout<<"n1) Recorrido
por Inicion2)
Recorrido por
Finaln3) Busquedan";
cout<<"4)
Insercionn5) Eliminar
un Daton6)
Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas
hacer: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido(1);
break;
case 2:
tec.Recorrido(2);
break;
case 3:
cout<<"Que Numero de
Control deseas
buscar?"<<endl;
cin>>res;
res=tec.Busqueda(res);
if(res==-999)
cout<<"Dato no
encontrado";
break;
case 4:
cout<<"Que nombre
quieres
Insertar?"<<endl;
gets(inom);
cout<<"Cual es su
Numero de
Control?"<<endl;
cin>>in_c;
cout<<"Cual es su
Edad?"<<endl;
cin>>iedad;
res=tec.Enca(in_c);
tec.InsLug(inom,in_c,
iedad,res);
break;
case 5:
cout<<"Que Numero de
Control deseas
eliminar?"<<endl;
cin>>res;
tec.Borrar(res);
break;
case 6:
cout<<"Salida...";
break;
default:
cout<<"Opcion
Erronea"<<endl;
break;
}
getch();
}
}
42
3.4 Listas Circulares:
Recorrido simplemente despliega los datos almacenados en el arreglo Info, con ayuda de
un segundo arreglo llamado Índice el cual guarda el orden en el que encuentran enlazados
cada uno de los datos.
Detalle:
Apuntador toma el valor de Indice[Inicio], después ve si la condición cumple para
efectuar un Ciclo mientras Apuntador sea diferente de Inicio, si cumple lo que hace es que
despliega la Info[Apuntador], después Apuntador toma el valor de
Indice[Apuntador] (El cual nos indica el siguiente nodo que sigue en la lista) y hace
esto hasta que Apuntador sea igual a Inicio (Cuando llega a este punto a llegado al fin de la
Lista).
Algoritmo:
Recorrido(Inicio, Info, Indice)
Apuntador → Indice[Inicio]
Repetir mientras Apuntador ≠ Inicio
Imprimir Info[Apuntador]
Apuntador → Indice[Apuntador]
Fin del ciclo
Salir
Diagrama:
43
Programa:
#include <conio.h>
#include <iostream.h>
void Recorrido(char Info[8][2],int Indice[8],int Inicio,int Disp);
void main()
{
char Info[8][2]={{" "},{"I"},{" "},{"T"},{"O"},{"A"},
{"G"},{"T"}};
int Indice[8]={6,7,-999,1,0,3,5,4};
int Inicio=0,Disp=2;
cout<<"El Recorrido es:n";
Recorrido(Info,Indice,Inicio,Disp);
getch();
}
void Recorrido(char Info[8][2],int Indice[8],int Inicio,int Disp)
{
int Apuntador=Indice[Inicio];
while(Apuntador!=Inicio)
{
cout<<Info[Apuntador];
Apuntador=Indice[Apuntador];
}
}
Corrida:
Búsqueda
La Búsqueda su objetivo es encontrar un dato en el arreglo Info, si lo encuentra lo
desplegara en la pantalla, si no lo encuentra no desplegara nada ya que el dato no se
encuentra en el arreglo Info.
44
Detalle:
Apuntador toma el valor de Inicio, después ve si la condición cumple para efectuar un
Ciclo mientras Apuntador sea diferente de 0, si cumple lo que hace a continuación es la
comparación de Elemento (El dato que vamos a buscar) con Info[Apuntador], cuando
lo encuentre lo despliega y sale del método. Si no, regresa el valor de Apuntador para así
saber que no se encontró el dato.
Algoritmo:
Recorrido(Inicio, Info, Indice, Elemento)
Apuntador → Indice[Inicio]
Repetir mientras Apuntador ≠ Inicio
Si Elemento = Info[Apuntador] entonces:
Imprimir Info[Apuntador]
Regresa Apuntador
Apuntador → Indice[Apuntador]
Fin del ciclo
Regresar Apuntador
Diagrama:
45
Programa:
#include <conio.h>
#include <iostream.h>
int Busqueda(int Info[8],int Indice[8],int Inicio,int Disp,int
Elemento);
void main()
{
int Info[8]={0,10,0,9,5,3,0,20};
int Indice[8]={5,7,6,1,0,3,-999,4};
int Inicio=0,Disp=2,Elemento,Res;
cout<<"Que Numero deseas buscar?";
cin>>Elemento;
Res=Busqueda(Info,Indice,Inicio,Disp,Elemento);
if(Res==-999)
cout<<"Dato No Encontrado...";
getch();
}
int Busqueda(int Info[8],int Indice[8],int Inicio,int Disp,int
Elemento)
{
int Apuntador=Indice[Inicio];
while(Apuntador!=Inicio)
{
if(Elemento==Info[Apuntador])
{
cout<<"Numero "<<Info[Apuntador]<<" encontrado...";
return Apuntador;
}
Apuntador=Indice[Apuntador];
}
return Apuntador;
}
46
Corrida:
Inserción al Principio
La Inserción al Principio básicamente busca si existe algún lugar disponible en el arreglo
Info y lo agrega como primer Nodo si es que es posible.
Detalle:
Hace una comparación para ver si es posible insertar otro Elemento al arreglo Info, para
esto checa si Disp es Diferente de Nulo. Si no cumple con la condición se desplegar “Sobre
Carga” ya que no se puede insertar un Nuevo Elemento. Si es cierto Apuntador toma el
valor de Inicio, Disp cambia a Indice[Disp] ya que el primer Disp tomara el valor del
Nuevo Elemento, después de esto solo copia la información de Elemento al arreglo Info en
la posición que guarda Apuntador, Indice[Apuntador] toma el valor de
Indice[Inicio] y finalmente Indice[Inicio] toma el valor de Apuntador.
Algoritmo:
InsPr(Inicio, Disp, Info, Indice, Elemento)
Si Disp ≠ Nill entonces:
Apuntador → Disp
Disp → Indice[Disp]
Info[Apuntador] → Elemento
Indice[Apuntador] → Indice[Inicio]
Indice[Inicio] → Apuntador
Si no:
Imprimir “Sobre Carga”
Salir
47
Diagrama:
Programa:
#include <conio.h>
#include
<iostream.h>
void Recorrido(int
Info[8],int
Indice[8],int
Inicio,int Disp);
void InsPr(int
Info[8],int
Indice[8],int
Inicio,int
Disp,int
Elemento);
void main()
{
int
Info[8]={0,10,0,9,
5,3,0,20};
int
Indice[8]={5,7,6,1
,0,3,-999,4};
int
Inicio=0,Disp=2,El
emento,Res;
cout<<"Lista
Originaln";
Recorrido(Info,Ind
ice,Inicio,Disp);
cout<<"Que Numero
deseas Insertar?";
cin>>Elemento;
InsPr(Info,Indice,
Inicio,Disp,Elemen
to);
getch();
}
void Recorrido(int
Info[8],int
Indice[8],int
Inicio,int Disp)
{
int
Apuntador=Indice[I
nicio];
while(Apuntador!=I
nicio)
{
cout<<Info[Apuntad
or]<<endl;
Apuntador=Indice[A
puntador];
}
}
void InsPr(int
Info[8],int
Indice[8],int
Inicio,int
Disp,int Elemento)
{
if(Disp!=-999)
{
int
Apuntador=Disp;
Disp=Indice[Disp];
Info[Apuntador]=El
emento;
Indice[Apuntador]=
Indice[Inicio];
Indice[Inicio]=Apu
ntador;
Recorrido(Info,Ind
ice,Inicio,Disp);
}
else
cout<<"Overflow...
";
}
48
Corrida:
Inserción después de un Nodo Determinado
La Inserción después de un Nodo Determinado básicamente hace lo mismo que la
inserción al principio, la única diferencia es que este recibe la posición del nodo en la que
será Insertada. Este Algoritmo se usa para Inserción Ordenada que más adelante
explicaremos.
Detalle:
Primero confirma que sea posible insertar el Dato, si no es posible solo desplegara “Sobre
Carga”. Si es posible insertar un dato nuevo lo posiciona en la primer posición Disponible
en el arreglo Info, después compara la Nueva Posición (Npos) que le mandamos con
Nill si cumple la condición el dato es insertado en la primer posición, de otra forma se
posicionara en la posición que guarde Npos.
Algoritmo:
InsOrd(Inicio, Disp, Info, Indice, Elemento, Npos)
Si Disp ≠ Nill entonces:
Apuntador → Disp
Disp → Indice[Disp]
Info [Apuntador] → Elemento
Si Npos = Nill entonces:
Indice[Apuntador] → Indice[Inicio]
Indice[Inicio] → Apuntador
Si no:
Indice[Apuntador] → Indice[Npos]
Indice[Npos] → Apuntador
Si no:
Imprimir “Sobre Carga”
Salir
Inserción Ordenada
La Inserción Ordenada busca la posición en donde será Insertado el Elemento y la posición
anterior donde será Insertado, después de encontrar la posición en la que será Insertado
49
el Elemento nos regresa ese valor y lo mandamos al método de la Inserción después de un
Nodo.
Detalle:
En esta ocasión usaremos dos variables para determinar la posición deseada, comparamos
si Indice[Inicio] es igual a Inicio ó si Elemento es menor al dato que se encuentra en
Info[Inicio], si alguna de las dos cumple regresamos Nill, de esta manera Indicamos
que el Elemento será el primero de todo el Arreglo Info, si no es así Temp tomara el valor
de Inicio y Temp2 de la posición que le sigue a Inicio. Hace un ciclo hasta encontrar la
posición en donde se insertara el Nuevo Elemento y va moviéndose de posición con las
variables Temp y Temp2 para así determinar que posición debe de regresar.
Algoritmo:
InsOrd(Inicio, Info, Indice, Elemento)
Si Inicio = Indice[Inicio] ó Elemento < Info[Inicio] entonces:
Regresar Nill
Temp → Indice[Inicio]
Temp2 → Indice[Temp]
Repetir mientras Temp2 ≠ Inicio
Si Elemento < Info[Temp2]
Regresar Temp
Temp → Temp2
Temp2 → Indice[Temp2]
Regresar Temp
Diagrama:
50
Programa:
#include <stdio.h>
#include <conio.h>
#include
<iostream.h>
void
Recorrido(char
Info[8][10],int
Indice[8],int
Inicio,int Disp);
void InsPr(char
Info[8][10],int
Indice[8],int
Inicio,int
Disp,char
Elemento[10]);
void InsOrd(char
Info[8][10],int
Indice[8],int
Inicio,int
Disp,char
Elemento[10]);
void main()
{
char
Info[8][10]={{"Cab
eza"},{"e"},{"
"},{"c"},{"i"},{"a
"},{" "},{"g"}};
char Elemento[10];
int
Indice[8]={5,7,6,1
,0,3,-999,4};
int
Inicio=0,Disp=2,Re
s;
cout<<"Lista
Originaln";
Recorrido(Info,Ind
ice,Inicio,Disp);
cout<<"Que Numero
deseas Insertar?";
gets(Elemento);
InsOrd(Info,Indice
,Inicio,Disp,Eleme
nto);
getch();
}
void
Recorrido(char
Info[8][10],int
Indice[8],int
Inicio,int Disp)
{
int
Apuntador=Indice[I
nicio];
while(Apuntador!=I
nicio)
{
cout<<Info[Apuntad
or]<<endl;
Apuntador=Indice[A
puntador];
}
}
void InsPr(char
Info[8][10],int
Indice[8],int
Inicio,int
Disp,char
Elemento[10])
{
if(Disp!=-999)
{
strcpy(Info[Disp],
Elemento);
Indice[Disp]=Indic
e[Inicio];
Indice[Inicio]=Dis
p;
Disp=Indice[Disp];
}
Recorrido(Info,Ind
ice,Inicio,Disp);
}
void InsOrd(char
Info[8][10],int
Indice[8],int
Inicio,int
Disp,char
Elemento[10])
{
if(Inicio==Indice[
Inicio]||(strcmp(E
lemento,Info[Indic
e[Inicio]]))==0)
{
InsPr(Info,Indice,
Inicio,Disp,Elemen
to);
return;
}
int
Temp=Indice[Inicio
],Temp2=Indice[Tem
p];
while(Temp2!=Inici
o)
{
if((strcmp(Element
o,Info[Temp2]))<0)
break;
Temp=Temp2;
Temp2=Indice[Temp2
];
}
strcpy(Info[Disp],
Elemento);
Indice[Disp]=Indic
e[Temp];
Indice[Temp]=Disp;
Disp=Indice[Disp];
Recorrido(Info,Ind
ice,Inicio,Disp);
}
51
Eliminación por Búsqueda
La Eliminación simplemente cambia los nodos para que el dato que se desea eliminar sea
el primer disponible, de esta forma ya no estará en el Arreglo de Info.
Detalle:
Lo primero que hace es ver si existe algún dato en la lista para eliminar, si
Indice[Inicio] es igual a Inicio entonces solo desplegara “Imposible Eliminar”. De otra
formas cambiar de Posición en Posición hasta encontrar el Elemento que sea desea
Eliminar con ayudar de dos variables que guardan la Posición actual y la anterior en donde
se encuentre el dato. Ya que lo encuentra cambia ese dato como la primera posición
Disponible y lo apunta al siguiente nodo disponible. Si no encuentra el dato simplemente
desplegara “Dato no encontrado”
Algoritmo:
EliBusq(Inicio, Info, Indice, Elemento)
Temp → Indice[Inicio]
Si Temp = Inicio
Imprimir “Lista Vacia… Imposible Eliminar” y Retornar
Repetir mientras Temp ≠ Inicio
Si Elemento = Info[Temp] entonces:
Si Temp = Indice[Inicio] entonces:
Indice[Inicio] → Indice[Indice[Inicio]]
Si no:
Indice[Temp2] → Indice[Temp]
Indice[Temp] → Disp
Disp → Temp
Recorrido(Inicio, Info, Indice) y Retornar
Si no:
Temp2 → Temp
Temp → Indice[Temp]
Imprimir “Dato no encontrado… Imposible Eliminar” y Retornar
Diagrama:
52
Programa:
#include <conio.h>
#include
<iostream.h>
void Recorrido(int
Info[8],int
Indice[8],int
Inicio,int Disp);
void EliBusq(int
Info[8],int
Indice[8],int
Inicio,int
Disp,int
Elemento);
void main()
{
int
Info[8]={0,10,0,9,
5,3,0,20};
int
Indice[8]={5,7,6,1
,0,3,-999,4};
int
Inicio=0,Disp=2,El
emento,Res;
cout<<"Lista
Originaln";
Recorrido(Info,Ind
ice,Inicio,Disp);
cout<<"Que Numero
deseas Eliminar?";
cin>>Elemento;
EliBusq(Info,Indic
e,Inicio,Disp,Elem
ento);
getch();
}
void Recorrido(int
Info[8],int
Indice[8],int
Inicio,int Disp)
{
int
Apuntador=Indice[I
nicio];
while(Apuntador!=I
nicio)
{
cout<<Info[Apuntad
or]<<endl;
Apuntador=Indice[A
puntador];
}
}
void EliBusq(int
Info[8],int
Indice[8],int
Inicio,int
Disp,int Elemento)
{
int
Temp=Indice[Inicio
],Temp2;
if(Temp==Inicio)
{
cout<<"Lista
Vacia... Imposible
Eliminar";
return;
}
while(Temp!=Inicio
)
{
if(Elemento==Info[
Temp])
{
if(Temp==Inicio)
Inicio=Indice[Inic
io];
else
Indice[Temp2]=Indi
ce[Temp];
Indice[Temp]=Disp;
Disp=Temp;
Recorrido(Info,Ind
ice,Inicio,Disp);
return;
}
else
{
Temp2=Temp;
Temp=Indice[Temp];
}
}
cout<<"Dato no
encontrado...
Imposible
Eliminar";
return;
}
53
Corrida:
3.5 Listas Dobles:
El Recorrido simplemente despliega los datos almacenados en el arreglo Info, con
ayuda de un segundo arreglo llamado Indice1 o Indice2 el cual guarda el orden en el
que encuentran enlazados cada uno de los datos. Estos datos se pueden recorrer de
Arriba hacia Abajo o de Abajo hacia Arriba.
Explicación:
Dependiendo de la forma en la que se desea recorrer el Arreglo, la variable Apuntador
tomara el valor de Indice1[Inicio], o de Fin. Después recorrerá el Arreglo mientras la
condición no se rompa (Dicha condición será diferente dependiendo el caso).
Diagrama:
Búsqueda
La Búsqueda su objetivo es encontrar un dato en el arreglo Info, si lo encuentra lo
desplegara en la pantalla, si no lo encuentra no desplegara nada ya que el dato no se
54
encuentra en el arreglo Info. Esta búsqueda es más efectiva ya que compara el dato de la
mitad y dependiendo el resultado, empezara la búsqueda por el Final o Inicio.
Explicación:
Primeramente usaremos un contador y la cabecera, esto nos permitirá determinar cuál es
dato de la mitad. Para esto se utiliza el Recorrido el cual al encontrar el Dato de la mitad lo
copia ese dato a la cabecera con la cual se comparara para determinar por dónde empezar
(Inicio y Fin).
Diagrama:
Inserción Ordenada
Definición:
La Inserción Ordenada busca la posición en donde será Insertado el Elemento y la posición
anterior donde será Insertado, después de encontrar la posición en la que será Insertado
el Elemento nos regresa ese valor y lo mandamos al método de la Inserción después de un
Nodo.
Explicación:
Esta Inserción ordenada es similar a las anteriores aunque en este caso consta de mas
comparación y movimientos de variables, esto se debe a que tenemos 2 arreglos que nos
indican los movimientos y al insertar un dato ambos arreglos deben direccionar
nuevamente.
55
Diagrama:
Eliminación por Búsqueda
La Eliminación simplemente cambia los nodos para que el dato que se desea eliminar sea
el primer disponible, de esta forma ya no estará en el Arreglo de Info.
Explicación:
Lo primero que hace es ver si existe algún dato en la lista para eliminar, si
Indice[Inicio] es igual a Inicio entonces solo desplegara “Imposible Eliminar”. De otra
formas cambiar de Posición en Posición hasta encontrar el Elemento que sea desea
Eliminar con ayudar de dos variables que guardan la Posición actual y la anterior en donde
se encuentre el dato. Ya que lo encuentra cambia ese dato como la primera posición
Disponible y lo apunta al siguiente nodo disponible. Si no encuentra el dato simplemente
desplegara “Dato no encontrado”
56
Diagrama:
Corrida:
57
#include <stdio.h>
#include <conio.h>
#include <iomanip.h>
#include <iostream.h>
class Alumno
{
private:
char Nombre[10][30];
int
N_control[10],Edad[10]
,Indice1[10],Indice2[
10],Inicio,Fin,Disp;
public:
//Constructor
Alumno()
{
int i,j;
Inicio=0;
Fin=0;
Disp=1;
Indice1[Inicio]=-999;
Indice2[Fin]=-999;
for(i=1,j=2;i<9;i++,
j++)
Indice1[i]=j;
Indice1[9]=-999;
}
//Funcion de Recorrido
void Recorrido(int op)
{
int i=0,Temp;
if(op==1)
{
Temp=Indice1[Inicio];
if(Temp!=-999)
{
cout<<"Numero de
Control"<<setw(19)
<<"Nombre del
Alumno"<<setw(5)
<<"Edad"<<endl;
while(Temp!=-999)
{
if(i==(int(Edad[Inicio
]/2)))
{
N_control[Inicio]=
N_control[i];
strcpy(Nombre[Inicio],
Nombre[i]);
}
cout<<setw(9)
<<N_control[Temp]
<<setw(22)
<<Nombre[Temp]
<<setw(9)
<<Edad[Temp]<<endl;
Temp=Indice1[Temp];
i++;
}
}
else
cout<<"Lista Vacia..";
}
if(op==2)
{
Temp=Fin;
if(Edad[Inicio]!=0)
{
cout<<"Numero de
Control"<<setw(19)
<<"Nombre del
Alumno"<<setw(5)
<<"Edad"<<endl;
while(Temp!=-
999&&i<Edad[Inicio])
{
if(i==(int(Edad[Inicio
]/2)))
{
N_control[Inicio]=
N_control[i];
strcpy(Nombre[Inicio],
Nombre[i]);
}
cout<<setw(9)
<<N_control[Temp]
<<setw(22)<<Nombre[
Temp]<<setw(9)
<<Edad[Temp]<<endl;
Temp=Indice2[Temp];
i++;
}
}
else
cout<<"Lista Vacia..";
}
}
//Funcion Sobrecargada
de Busqueda para
Enteros
int Busqueda(int Elem)
{
if(Elem<N_control[
Inicio])
{
int
Temp=Indice1[Inicio];
while(Temp!=-999)
{
if(Elem==N_control[
Temp])
{
gotoxy(1,10);
cout<<"Numero de
Control"<<setw(19)
<<"Nombre del
Alumno"<<setw(5)
<<"Edad"<<endl;
cout<<setw(9)
<<N_control[Temp]
<<setw(22)<<Nombre[
Temp]<<setw(9)
<<Edad[Temp]<<endl;
return Temp;
}
else
Temp=Indice1[Temp];
}
}
else
{
int Temp=Fin;
while(Temp!=-999)
{
if(Elem==N_control[
Temp])
{
gotoxy(1,10);
cout<<"Numero de
Control"<<setw(19)
<<"Nombre del
Alumno"<<setw(5)
<<"Edad"<<endl;
cout<<setw(9)
<<N_control[Temp]
<<setw(22)<<Nombre[
58
Temp]<<setw(9)<<Edad[
Temp]<<endl;
return Temp;
}
else
Temp=Indice2[Temp];
}
}
return -999;
}
//Funcion Sobrecargada
de Busqueda de Cadenas
de Caracteres
int Busqueda(char
Elem[30])
{
if((strcmp(Elem,Nombre
[Inicio]))<0)
{
int
Temp=Indice1[Inicio];
while(Temp!=-999)
{
if((strcmp(Elem,Nombre
[Temp]))==0)
{
gotoxy(1,10);
cout<<"Numero de
Control"<<setw(19)
<<"Nombre del
Alumno"<<setw(5)
<<"Edad"<<endl;
cout<<setw(9
)<<N_control[Temp]
<<setw(22)<<Nombre[
Temp]<<setw(9)<<Edad[
Temp]<<endl;
return Temp;
}
else
Temp=Indice1[Temp];
}
}
else
{
int Temp=Fin;
while(Temp!=-999)
{
if((strcmp(Elem,Nombre
[Temp]))==0)
{
gotoxy(1,10);
cout<<"Numero de
Control"<<setw(19)
<<"Nombre del
Alumno"<<setw(5)
<<"Edad"<<endl;
cout<<setw(9)
<<N_control[Temp]
<<setw(22)<<Nombre[
Temp]<<setw(9)<<Edad[
Temp]<<endl;
return Temp;
}
else
Temp=Indice2[Temp];
}
}
return -999;
}
//Funcion Sobrecargada
de Orden para Numeros
Enteros
int Enca(int E_nc)
{
int
Temp=Indice1[Inicio],T
emp2;
if(Temp==-
999||E_nc<N_control[
Temp])
return -999;
Temp2=Indice1[Indice1[
Inicio]];
while(Temp2!=-999)
{
if(E_nc<N_control[
Temp2])
return Temp;
Temp=Temp2;
Temp2=Indice1[Temp2];
}
return Temp;
}
//Funcion Sobrecargada
de Orden para Cadena
de Caracteres
int Enca(char
E_nom[30])
{
int
Temp=Indice1[Inicio],
Temp2;
if(Temp==-999)
return -999;
if((strcmp(E_nom,
Nombre[Temp]))<0)
return Temp;
Temp2=Indice1[Indice1[
Inicio]];
while(Temp2!=-999)
{
if((strcmp(E_nom,
Nombre[Temp2]))<0)
return Temp;
Temp=Temp2;
Temp2=Indice1[Temp2];
}
return Temp;
}
//Funcion de Inserción
en un Lugar
Determinado
void InsLug(char
E_nom[30],int E_nc,int
E_edad,int Npos)
{
if(Disp!=-999)
{
Edad[Inicio]++;
int Temp=Disp;
Disp=Indice1[Disp];
strcpy(Nombre[Temp],
E_nom);
N_control[Temp]=E_nc;
Edad[Temp]=E_edad;
if(Npos==-999)
{
Indice1[Temp]=Indice1[
Inicio];
if(Indice2[Fin]==-999)
{
Indice2[Temp]=Fin;
Fin=Temp;
}
else
59
{
Indice2[Temp]=Indice1[
Inicio];
Indice2[Indice1[
Inicio]]=Temp;
}
Indice1[Inicio]=Temp;
}
else
{
Indice1[Temp]=Indice1[
Npos];
if(Fin==Npos)
{
Indice2[Temp]=Fin;
Fin=Temp;
}
else
{
Indice2[Temp]=Npos;
Indice2[Indice1[Npos]]
=Temp;
}
Indice1[Npos]=Temp;
}
}
else
cout<<"Overflow..."
<<endl;
}
//Funcion Sobrecargada
para Borrar un Dato
que sea Entero
void Borrar(int Elem)
{
int
Temp2,Temp=Indice1[Ini
cio];
if(Temp==-999)
{
cout<<"Lista Vacia...
Imposible Eliminar";
return;
}
while(Temp!=-999)
{
if(Elem==N_control[
Temp])
{
Edad[Inicio]--;
if(Temp==Indice1[
Inicio])
{
Indice1[Inicio]=Indice
1[Indice1[Inicio]];
Indice2[Indice1[
Inicio]]=Inicio;
}
else if(Temp==Fin)
{
Indice1[Temp2]=Indice1
[Temp];
Fin=Indice2[Fin];
}
else
{
Indice1[Temp2]=Indice1
[Temp];
Indice2[Indice1[
Temp2]]=Temp2;
}
Indice1[Temp]=Disp;
Disp=Temp;
return;
}
else
{
Temp2=Temp;
Temp=Indice1[Temp];
}
}
cout<<"Dato no
encontrado...
Imposible Eliminar";
return;
}
//Funcion Sobrecargada
para Borrar una Cadena
de Caracteres
void Borrar(char
Elem[30])
{
int
Temp2,Temp=Indice1[
Inicio];
if(Temp==Inicio)
{
cout<<"Lista Vacia...
Imposible Eliminar";
return;
}
while(Temp!=Inicio)
{
if((strcmp(Elem,Nombre
[Temp]))==0)
{
Edad[Inicio]--;
if(Temp==Indice1[
Inicio])
{
Indice1[Inicio]=Indice
1[Indice1[Inicio]];
Indice2[Indice1[
Inicio]]=Inicio;
}
else if(Temp==Fin)
{
Indice1[Temp2]=Indice1
[Temp];
Fin=Indice2[Fin];
}
else
{
Indice1[Temp2]=Indice1
[Temp];
Indice2[Indice1[
Temp2]]=Temp2;
}
Indice1[Temp]=Disp;
Disp=Temp;
return;
}
else
{
Temp2=Temp;
Temp=Indice1[Temp];
}
}
cout<<"Dato no
encontrado...
Imposible Eliminar";
return;
}
}tec;
main()
{
int op=0,res;
char inom[30];
int in_c,iedad;
60
while(op!=6)
{
clrscr();
cout<<"n1) Recorrido
por Inicion2)
Recorrido por
Finaln3) Busquedan";
cout<<"4)
Insercionn5)
Eliminar un Daton6)
Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas
hacer: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido(1);
break;
case 2:
tec.Recorrido(2);
break;
case 3:
cout<<"Que Numero de
Control deseas
buscar?"<<endl;
cin>>res;
res=tec.Busqueda(res);
if(res==-999)
cout<<"Dato no
encontrado";
break;
case 4:
cout<<"Que nombre
quieres
Insertar?"<<endl;
gets(inom);
cout<<"Cual es su
Numero de
Control?"<<endl;
cin>>in_c;
cout<<"Cual es su
Edad?"<<endl;
cin>>iedad;
res=tec.Enca(in_c);
tec.InsLug(inom,in_c,i
edad,res);
break;
case 5:
cout<<"Que Numero de
Control deseas
eliminar?"<<endl;
cin>>res;
tec.Borrar(res);
break;
case 6:
cout<<"Salida...";
break;
default:
cout<<"Opcion
Erronea"<<endl;
break;
}
getch();
}
}
61
Unidad 4: Recursividad
Capacidad que tiene los métodos de invocarse a sí mismos, esta es una potente
herramienta en la informática.
Con esta herramienta muchos algoritmos pueden simplificarse significativamente.
Programa:
#include <stdio.h>
#include <conio.h>
#include
<string.h>
#include
<iomanip.h>
#include
<iostream.h>
class Matematicas
{
public:
void Tablas(int
T,int B)
{
if(B<11)
{
cout<<T<<" X
"<<setw(2)<<B<<" =
"<<(T*B)<<endl;
Tablas(T,B+1);
}
return;
}
long
Factorial(long n)
{
if(n<=1)
return 1;
else
return (n*
Factorial(n - 1));
}
void Formula(int
X)
{
if(X<11)
{
cout<<"f("<<X<<")
=
"<<((X*X*X)+(2*X)+
(3))<<endl;
Formula(X+1);
}
return;
}
void Torres(int
N,char Inicio,char
Aux,char Fin)
{
if(N==1)
{
cout<<Inicio<<" --
> "<<Fin<<endl;
return;
}
Torres(N-
1,Inicio,Fin,Aux);
cout<<Inicio<<" --
> "<<Fin<<endl;
Torres(N-
1,Aux,Inicio,Fin);
return;
}
}tec;
main()
{
int t,b,op=0;
while(op!=5)
{
clrscr();
cout<<"n1) Tablas
de Multiplicarn2)
Factorial de un
Numeron";
cout<<"3) Formula
Linealn4) Torres
de Hanoin5)
Salida"<<endl;
gotoxy(1,1);
cout<<"Que deseas
hacer: ";
cin>>op;
clrscr();
switch(op)
{
case 1:
cout<<"Que Tabla
de Multiplicar
deseas
Imprimir?"<<endl;
cin>>t;
cout<<"Desde que
Numero deseas
empezar a
multiplicar (Menor
que 10)"<<endl;
cin>>b;
tec.Tablas(t,b);
break;
case 2:
cout<<"Que
Factorial deseas
conocer"<<endl;
cin>>t;
62
cout<<t<<"! =
"<<tec.Factorial(t
)<<endl;
break;
case 3:
cout<<"f(x) = x^3
+ 2x + 3"<<endl;
cout<<"Escribe la
Base (Menor de
10)"<<endl;
cin>>t;
tec.Formula(t);
break;
case 4:
cout<<"Cuantos
discos deseas
mover?"<<endl;
cin>>t;
tec.Torres(t,'A','
B','C');
break;
case 5:
cout<<"Salida...";
break;
default:
cout<<"Opcion
Erronea...";
break;
}
getch();
}
}
63
Unidad 5: Arboles
5.1 Arboles Binarios:
Un Árbol Binario es un conjunto de finito de Elementos, de nombre Nodos de forma que:
El Árbol Binario es Vació si no tiene ningún elemento en él.
El Árbol Binario contiene un Nodo Raíz y los dos que parten de él, llamados Nodo
Izquierdo y Nodo Derecho.
Los Árboles tienen 3 Recorridos Diferentes los cuales son:
• Pre-Orden
• In-Orden
• Post-Orden
• Pre-Orden
El Recorrido “Pre-Orden” lo recorre de la siguiente manera, viaje a través del Árbol
Binario desplegando el Contenido en la Raíz, después viaje a través del Nodo Izquierdo y
después a través del Nodo Derecho.
Detalle:
Temp toma el Valor de la Raíz y compara si el Árbol tiene algún Elemento, de otra manera
Desplegara “Árbol Vació…” y terminara el método. Si el Árbol tiene elementos dentro de
él, lo recorrerá y viajara a través de los Arreglos Izq y Der para determinar qué valor
meter en la Pila y en Temp para de esta manera imprimir el siguiente Elemento
correspondiente.
Algoritmo:
PreOrd(Arbol, Der, Izq, Pila, Raiz)
Temp → Raiz
Top →
Pila[Top] → Nulo
Si Raiz = Nulo
Imprimir “Árbol Vació…” y Salir
Repetir mientras Temp ≠ Nulo
Imprimir Arbol[Temp]
Si Der[Temp] ≠ Nulo
Top → Top + 1
Pila[Top] → Der[Temp]
Si Izq[Temp] ≠ Nulo
Temp → Izq[Temp]
Si no:
Temp → Pila[Top];
Top → Top - 1
Fin del ciclo
Salir
64
Diagrama:
Corrida:
In-Orden
El Recorrido “In-Orden” lo recorre de la siguiente manera, viaje a través del Árbol
Binario desplegando el Contenido en el Nodo Izquierdo después la Raíz y finalmente viaja
a través del Nodo Derecho.
Detalle:
Temp toma el Valor de la Raíz y compara si el Árbol tiene algún Elemento, de otra manera
Desplegara “Árbol Vació…” y terminara el método. Si el Árbol tiene elementos dentro de
él, lo recorrerá y viajara a través de los Arreglos Izq y Der para determinar qué valor
meter en la Pila y en Temp para de esta manera imprimir el siguiente Elemento
correspondiente.
65
Algoritmo:
PreOrd(Arbol, Der, Izq, Pila, Raiz)
Temp → Raiz
Top →
Pila[Top] → Nulo
Si Raiz = Nulo
Imprmir “Arbol Vacio…” y Salir
Etiqueta:
Mientras Temp ≠ Nulo
Top → Top + 1
Pila[Top] → Temp
Temp → Izq[Temp]
Fin del ciclo
Temp → Pila[Top]
Top → Top - 1
Mientras Temp ≠ Nulo
Imprimir Arbol[Temp]
Si Der[Temp] ≠ Nulo
Temp → Der[Temp]
Ir a Etiqueta
Temp → Pila[Top]
Top → Top - 1
Fin del ciclo
Salir
Diagrama:
66
Corrida:
In-Orden
El Recorrido “In-Orden” lo recorre de la siguiente manera, viaje a través del Árbol Binario
desplegando el Contenido en el Nodo Izquierdo después el Nodo Derecho y finalmente
viaja a través de la Raiz.
Detalle:
Temp toma el Valor de la Raíz y compara si el Árbol tiene algún Elemento, de otra manera
Desplegara “Árbol Vació…” y terminara el método. Si el Árbol tiene elementos dentro de
él, lo recorrerá y viajara a través de los Arreglos Izq y Der para determinar que valor meter
en la Pila y en Temp para de esta manera imprimir el siguiente Elemento correspondiente.
Algoritmo:
PostOrd(Arbol, Der, Izq, Pila, Raiz)
Temp → Raiz
Top →
Pila[Top] → Nulo
Si Raiz = Nulo
Imprimir “Arbol Vacio…” y Salir
Etiqueta:
Mientras Temp ≠ Nulo
Top → Top + 1
Pila[Top] → Temp
Si Der[Temp] ≠ Nulo
Top → Top + 1
Pila[Top] → - (Der[Temp])
Temp → Izq[Temp]
Temp → Pila[Top]
Top → Top - 1
Fin del ciclo
Mientras Temp ≥ 0
Imprimir Arbol[Temp]
67
Si Arbol[Temp] = Info[Raiz]
Salir
Temp → Pila[Top]
Top → Top - 1
Fin del ciclo
Si Temp < 0
Temp = -(Temp)
Ir a Etiqueta
Salir
Diagrama:
Corrida:
68
Búsqueda
La Búsqueda es Similar a todas los Métodos anteriores de Búsqueda, simplemente efectúa
un recorrido comparando el Elemento que deseas encontrar contra cada uno de los
Elementos en los Arreglos.
Detalle:
El Algoritmo de Búsqueda compara el Elemento a buscar con cada uno de los datos de
nuestro Árbol, compara si el Elemento con el Nodo Raíz, si no se encuentra en la Raíz…
compara Elemento contra la Raíz para empezar a viajar por el Árbol respectivamente, usa
un método similar al anterior hasta encontrar el Elemento. De otra forma la búsqueda es
fallida.
Algoritmo:
Busqueda(Arbol, Der, Izq,
Pila, Raiz, Elem)
Si Raiz = Nulo
Imprimir “Arbol Vacio”
Pos → Nulo
Pad → Nulo
Regresar Pos y Pad
Salir
Si Elem = Arbol[Raiz]
Imprimir “Elemento Encontrado”
Pos → Raiz
Pad → Nulo
Regresar Pos y Pad
Salir
Si Elem < Arbol[Raiz]
Temp → Izq[Raiz]
Temp2 → Raiz
Si no:
Temp → Der[Raiz]
Temp2 → Raiz
Mientras Temp ≠ Nulo
Si Elem = Arbol[Temp]
Imprimir “Elemento
Encontrado…”
Pos → Temp
Pad → Temp2
Regresar Pos y Pad
Salir
Si Elem < Arbol[Temp]
Temp2 → Temp
Temp → Izq[Temp]
Si no:
Temp2 → Temp
Temp → Der[Temp]
Fin del ciclo
Imprimir “Elemento no
Encontrado…”
Pos → Nulo
Pad → Temp2
Regresar Pos y Pad
Salir
69
Diagrama:
Corrida:
70
#include <conio.h>
#include <iostream.h>
class Arbol
{
private:
int Top,Pila[10];
int
Info[10],Izq[10],Der[1
0],Raiz,Disp;
public:
Arbol()
{
int
in[10]={0,0,0,0,0,0,0,
0,0,0};
for(int i=0;i<10;i++)
{
Info[i]=0;
Izq[i]=i+1;
Der[i]=-999;
Pila[i]=0;
}
Top=0;
Disp=0;
Raiz=-999;
Izq[9]=-999;
}
void PreOrd(void)
{
int Temp=Raiz;
Top=0;
Pila[0]=-999;
if(Raiz==-999)
{
cout<<"Arbol
Vacio..."<<endl;
return;
}
while(Temp!=-999)
{
cout<<Info[Temp]
<<endl;
if(Der[Temp]!=-999)
{
Top++;
Pila[Top]=Der[Temp];
}
if(Izq[Temp]!=-999)
{
Temp=Izq[Temp];
}
else
{
Temp=Pila[Top];
Top--;
}
}
}
void InOrd(void)
{
int Temp=Raiz,
Top=0;
Pila[0]=-999;
if(Raiz==-999)
{
cout<<"Arbol
Vacio..."<<endl;
return;
}
Back:
while(Temp!=-999)
{
Top++;
Pila[Top]=Temp;
Temp=Izq[Temp];
}
Temp=Pila[Top];
Top--;
while(Temp!=-999)
{
cout<<Info[Temp]
<<endl;
if(Der[Temp]!=-999)
{
Temp=Der[Temp];
goto Back;
}
Temp=Pila[Top];
Top--;
}
}
void PostOrd(void)
{
int Temp=Raiz;
Top=0;
Pila[0]=-999;
if(Raiz==-999)
{
cout<<"Arbol
Vacio..."<<endl;
return;
}
Back1:
while(Temp!=-999)
{
Top++;
Pila[Top]=Temp;
if(Der[Temp]!=-999)
{
Top++;
Pila[Top]=-Der[Temp];
}
Temp=Izq[Temp];
}
Temp=Pila[Top];
Top--;
while(Temp>=0)
{
cout<<Info[Temp]
<<endl;
if(Info[Temp]==Info[
Raiz])
return;
Temp=Pila[Top];
Top--;
}
if(Temp<0)
{
Temp=-Temp;
goto Back1;
}
}
void Busqueda(int
PosPad[2],int Elem)
{
int Temp,Temp2;
if(Raiz==-999)
{
PosPad[0]=-999;
PosPad[1]=-999;
cout<<"Arbol
Vacio..."<<endl;
return;
}
if(Elem==Info[Raiz])
{
PosPad[0]=Raiz;
71
PosPad[1]=-999;
cout<<"Elemento
Encontrado..."<<endl;
return;
}
if(Elem<Info[Raiz])
{
Temp=Izq[Raiz];
Temp2=Raiz;
}
else
{
Temp=Der[Raiz];
Temp2=Raiz;
}
while(Temp!=-999)
{
if(Elem==Info[Temp])
{
cout<<"Elemento
Encontrado..."<<endl;
PosPad[0]=Temp;
PosPad[1]=Temp2;
return;
}
if(Elem<Info[Temp])
{
Temp2=Temp;
Temp=Izq[Temp];
}
else
{
Temp2=Temp;
Temp=Der[Temp];
}
}
PosPad[0]=-999;
PosPad[1]=Temp2;
cout<<"Elemento no
Encontrado..."<<endl;
}
void InsOrd(int Elem)
{
int PosPad[2],Temp;
if(Disp!=-999)
{
Busqueda(PosPad,Elem);
clrscr();
if(PosPad[0]!=-999)
{
cout<<"Elemento
Existente... Imposible
Insertar..."<<endl;
return;
}
Temp=Disp;
Disp=Izq[Disp];
Info[Temp]=Elem;
PosPad[0]=Temp;
Izq[Temp]=-999;
Der[Temp]=-999;
if(PosPad[1]==-999)
Raiz=Temp;
else if(Elem<Info[
PosPad[1]])
Izq[PosPad[1]]=Temp;
else
Der[PosPad[1]]=Temp;
cout<<"Elemento
Insertado..."<<endl;
return;
}
cout<<"Arbol Lleno...
Imposible
Insertar..."<<endl;
}
void Eliminar(int
Elem)
{
int PosPad[2];
Busqueda(PosPad,Elem);
clrscr();
if(PosPad[0]==-999)
{
cout<<"El Elemento no
se Encuentra en el
Arbol... Imposible
Eliminar..."<<endl;
return;
}
if(Der[PosPad[0]]!=-
999&&Izq[PosPad[0]]!=-
999)
CasoB(PosPad);
else
CasoA(PosPad);
Izq[PosPad[0]]=Disp;
Disp=PosPad[0];
}
void CasoA(int
PosPad[2])
{
int Temp;
if(Izq[PosPad[0]]==-
999&&Der[PosPad[0]]==-
999)
Temp=-999;
else
if(Izq[PosPad[0]]!=-
999)
Temp=Izq[PosPad[0]];
else
Temp=Der[PosPad[0]];
if(PosPad[1]!=-999)
{
if(PosPad[0]==Izq[PosP
ad[1]])
Izq[PosPad[1]]=Temp;
else
Der[PosPad[1]]=Temp;
}
else
Raiz=Temp;
}
void CasoB(int
PosPad[2])
{
int
PosPad2[2],Temp=Der[Po
sPad[0]],Temp2=PosPad[
0];
while(Izq[Temp]!=-999)
{
Temp2=Temp;
Temp=Izq[Temp];
}
PosPad2[0]=Temp;
PosPad2[1]=Temp2;
CasoA(PosPad2);
if(PosPad[1]!=-999)
{
if(PosPad[0]==Izq[PosP
ad[1]])
Izq[PosPad[1]]=PosPad2
[0];
72
else
Der[PosPad[1]]=PosPad2
[0];
}
else
Raiz=PosPad2[0];
Izq[PosPad2[0]]=Izq[Po
sPad[0]];
Der[PosPad2[0]]=Der[
PosPad[0]];
}
}tec;
main()
{
int
PosPad[2],res,op=0;
while(op!=7)
{
clrscr();
cout<<"n1)
Pre-Ordenn2)
In-Ordenn3)
Post-Ordenn4)
Busquedan5)
Insercionn6)
Eliminarn7)
Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas
hacer?: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.PreOrd();
break;
case 2:
tec.InOrd();
break;
case 3:
tec.PostOrd();
break;
case 4:
cout<<"Que Numero
deseas buscar?"<<endl;
cin>>res;
tec.Busqueda(PosPad,
res);
break;
case 5:
cout<<"Que Numero
quieres
Insertar?"<<endl;
cin>>res;
tec.InsOrd(res);
break;
case 6:
cout<<"Que Numero
quieres
Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
break;
case 7:
cout<<"Salida...";
break;
default:
cout<<"Opcion
Erronea"<<endl;
break;
}
getch();
}
}
73
5.2 Arboles en Monton
El Árbol en Montón consiste en el ordenamiento de un conjunto de Elemento en un solo
arreglo.
Trabajaremos sobre la siguientes Operaciones en este Tema:
1. Inserción
2. Búsqueda
3. Eliminación
4. Recorrido (Ordenado)
Inserción
El Concepto de Inserción ya es familiar para nosotros y sabemos que para realizar el
mismo no resulta complejo el procedimiento.
Pero en los Árboles en Montón es uno de los Métodos más largos para efectuarlo.
Detalle:
Básicamente lo que hace estos Algoritmos es la Inserción Ordenada. Primero comparan si
es posible insertar algún Elemento al Arreglo, si es posible hacerlo Ingresa el Elemento a la
Última posición.
Después básicamente acomoda el Arreglo con el Método de la Burbuja llamando a otra
serie de Métodos.
Algoritmos:
Insertar(Arbol, N, Elemento)
Si N<25
Arbol[N] -> a
N -> N + 1
OrdMon(Arbol, N)
Salir
//Fin de la condición//
Imprimir "Árbol Lleno..."
Salir
OrdMon(Arbol, Total)
ConstMon(Arbol, Total)
Mientras Total > 1
Total -> Total - 1
Burbuja(0, Total)
RecMon(Total, 0)
//Fin del ciclo//
Salir
ConstMon(Arbol, Total)
v -> (Total/2) - 1
Mientras v ≥ 0
RecMon(Arbol, Total, v)
v -> v - 1
//Fin del ciclo//
Salir
----
RecMon(Arbol, Total, v)
w -> 2*v+1
Mientras w < Total
Si (w+1) < Total
Si Arbol[w+1] > Arbol[w]
w++
//Fin de la condición//
Fin de la condición
Si Arbol[v] ≥ Arbol[w]
Salir
//Fin de la condición//
Burbuja(Arbol, v, w)
v -> w
w -> 2*v+1
//Fin del ciclo//
Salir
----
Burbuja(Arbol, v, w)
t -> Arbol[v]
Arbol[v] -> Arbol[w]
Arbol[w] -> t
Salir
74
Diagrama:
Corrida:
Búsqueda
El Concepto de Búsqueda es sencillo, simplemente es un método de búsqueda lineal.
Existen 3 posible resultados:
1. Que el Árbol este Vació y no se puede realizar la búsqueda.
2. Que el Elemento sea encuentre en el Árbol
3. Que el Elemento no esté dentro del Árbol
Detalle:
Se manda al Método Búsqueda el Dato que se desea buscar, se acomoda el Árbol en
Orden en caso que no estuviera Ordenado y después compara con cada uno de los datos.
75
Algoritmos:
**Busqueda(Arbol, N, Elemento)**
Si N ≠ 0
OrdMon(Arbol, N)
i ->
Mientras i < N;i++)
Si Arbol[i] = Elemento
Imprimir "Elemento Encontrado..."
Salir
//Fin de la condición//
i -> i + 1
//Fin del ciclo//
Imprimir "El Elemento no esta en el Árbol..."
Salir
//Fin de la condición//
Imprimir "Árbol Vació..."
Salir
Diagrama:
76
Corrida:
Eliminación
El Concepto de Eliminación consiste en la búsqueda de un Elemento y sacarlo del Arreglo.
Existen 3 casos Diferentes;
1. Que el Árbol este Vació y no se puede realizar la eliminación
2. Que el Elemento sea encuentre en el Árbol y sea eliminado
3. Que el Elemento no esté dentro del Árbol por lo tanto no se elimina
Detalle:
Vemos si el Árbol tiene Elementos insertados en él, de otra forma será imposible realizar
la Eliminación ya que esta Vació. Después si el Árbol tiene Elementos lo ordenamos y
hacemos un búsqueda lineal para encontrar el dato. Después usamos el método de la
Burbuja para dejar el Elemento Eliminado hasta el final y le Restamos a N un Elemento.
Algoritmo:
Eliminar(Arbol, N, Elemento)
Si N ≠ 0
OrdMon(Arbol, N)
i ->
Mientras I < N
Si Arbol[i] = Elemento
j -> i + 1
Mientras j < N
t -> Arbol[i]
Arbol[i] -> Arbol[j]
Arbol[j] -> t
j -> j + 1
//Fin del ciclo//
N -> n - 1
Imprimir "Elemento
Eliminado..."
Salir
//Fin de la condición//
i -> i + 1
//Fin del ciclo//
Fin de la condición
Imprimir "Arbol Vacio...
Imposible Eliminar..."
Salir
77
Diagrama:
Corrida:
Recorrido (Ordenado)
El Recorrido simplemente ira desplegando cada uno de los Elementos del Árbol. Solo
existen 2 posibles casos:
1. Que el Árbol este Vació y no se pueda recorrer
2. El Árbol tenga Elementos para desplegar
Detalle:
Comparamos para comprobar que el Árbol tiene Elementos dentro de el, de ser así
Desplegamos cada uno de ellos. De otra manera Desplegamos Árbol Vació.
78
Algoritmo:
Recorrido(Arbol, N)
Si N ≠ 0
i ->
Mientras i < N
Imprimir Arbol[i]
i -> i + 1
//Fin del ciclo//
Salir
//Fin de la condición//
Imprimir "Arbol Vacio..."
Salir
Corrida:
79
#include <conio.h>
#include <iostream.h>
class Arbol_Monton
{
private:
int Arbol[25];
int N;
public:
Arbol_Monton()
{
for(int i=0;i<25;i++)
Arbol[i]=0;
N=0;
}
void Insertar(int a)
{
if(N<25)
{
Arbol[N]=a;
N++;
OrdMon(N);
return;
}
cout<<"Arbol
Lleno..."<<endl;
}
void Eliminar(int a)
{
int t;
if(N!=0)
{
OrdMon(N);
for(int i=0;i<N;i++)
{
if(Arbol[i]==a)
{
for(int j=i+1;j<N;j++)
{
t=Arbol[i];
Arbol[i]=Arbol[j];
Arbol[j]=t;
}
N--;
cout<<"Elemento
Eliminado..."<<endl;
return;
}
}
}
cout<<"Arbol Vacio...
Imposible
Eliminar..."<<endl;
}
void Busqueda(int a)
{
if(N!=0)
{
OrdMon(N);
for(int i=0;i<N;i++)
if(Arbol[i]==a)
{
cout<<"Elemento
Encontrado..."<<endl;
return;
}
cout<<"El Elemento no
esta en el
Arbol..."<<endl;
return;
}
cout<<"Arbol
Vacio..."<<endl;
}
void OrdMon(int n)
{
ConstMon(n);
while(n>1)
{
n--;
Burbuja(0,n);
RecMon(n,0);
}
}
void ConstMon(int n)
{
for(int v=n/2-
1;v>=0;v--)
RecMon(n,v);
}
void RecMon(int n,int
v)
{
int w=2*v+1;
while(w<n)
{
if(w+1<n)
if
(Arbol[w+1]>Arbol[w])
w++;
if(Arbol[v]>=Arbol[w])
return;
Burbuja(v,w);
v=w;
w=2*v+1;
}
}
void Burbuja(int i,int
j)
{
int t=Arbol[i];
Arbol[i]=Arbol[j];
Arbol[j]=t;
}
void Recorrido()
{
if(N!=0)
{
for(int i=0;i<N;i++)
cout<<Arbol[i]<<endl;
return;
}
cout<<"Arbol
Vacio..."<<endl;
}
}tec;
main()
{
int res,op=0;
while(op!=5)
{
clrscr();
cout<<"n1)
Recorridon2)
Busquedan3)
Insercionn4)
Eliminarn5)
Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas
hacer?: ";
cin>>op;
gotoxy(1,10);
80
switch (op)
{
case 1:
tec.Recorrido();
break;
case 2:
cout<<"Que Numero
deseas buscar?"<<endl;
cin>>res;
tec.Busqueda(res);
break;
case 3:
cout<<"Que Numero
quieres
Insertar?"<<endl;
cin>>res;
tec.Insertar(res);
break;
case 4:
cout<<"Que Numero
quieres
Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
break;
case 5:
cout<<"Salida...";
break;
default:
cout<<"Opcion
Erronea"<<endl;
break;
}
getch();
}
}
81
Unidad 6: Ordenamientos Internos
Introducción:
En esta Unidad explicaremos 4 algoritmos para el Ordenamiento de Arreglos en Memoria
Ram.
A continuación mencionaremos los diferentes métodos para ordenar:
1. Burbuja
2. ShellSort
3. RadixSort
4. QuickSort
Burbuja
El método de la burbuja es una comparación lineal con cada uno de los elementos, el
elemento que sea menor contra el que se está comparado intercambiaran posiciones.
Este método no es recomendado para grandes comparaciones, ya que es un proceso muy
lento y requiere de una gran cantidad de Memoria Ram.
Programa:
#include<conio.h>
#include<iostream.
h>
class Lista
{
private:
int Lista[10],N;
public:
Lista()
{
for(int
i=0;i<10;i++)
Lista[i]=0;
N=0;
}
void Burbuja(void)
{
if(N!=0)
{
int i,j,aux;
for(i=0;i<9;i++)
for(j=i+1;j<10;
j++)
if(Lista[i]<Lista[
j])
{
aux=Lista[i];
Lista[i]=Lista[j];
Lista[j]=aux;
}
cout<<"Lista
Ordenada..."
<<endl;
return;
}
cout<<"Lista
Vacia..."<<endl;
}
void Busqueda(int
Elem)
{
if(N!=0)
{
for(int
i=0;i<N;i++)
if(Lista[i]==Elem)
{
cout<<"El
"<<Elem<<" esta en
la Lista"<<endl;
return;
}
}
cout<<"Lista
Vacia..."<<endl;
return;
}
void Insertar(int
Elem)
{
if(N<10)
{
Lista[N]=Elem;
N++;
cout<<"El
"<<Elem<<" fue
Insertado"<<endl;
return;
}
cout<<"Lista
Llena... Imposible
Insertar"<<endl;
return;
}
void Eliminar(int
82
Elem)
{
if(N!=0)
{
for(int
i=0;i<N;i++)
if(Lista[i]==Elem)
{
Lista[i]=0;
Burbuja();
N--;
return;
}
}
cout<<"Lista
Vacia... Imposible
Eliminar..."
<<endl;
return;
}
void Recorrido()
{
if(N!=0)
{
for(int
i=0;i<N;i++)
cout<<Lista[i]
<<endl;
}
cout<<"Lista
Vacia..."<<endl;
}
}tec;
main()
{
int op=0,res;
while(op!=6)
{
clrscr();
cout<<"n1)
Recorridon2)
Ordenarn3)
Busquedan4)
Insercionn5)
Eliminar un
Daton6)
Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas
hacer: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido();
break;
case 2:
tec.Burbuja();
break;
case 3:
cout<<"Que Numero
de Control deseas
buscar?"<<endl;
cin>>res;
tec.Busqueda(res);
break;
case 4:
cout<<"Que Numero
Deseas
Insertar?"<<endl;
cin>>res;
tec.Insertar(res);
break;
case 5:
cout<<"Que Numero
de Control deseas
Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
break;
case 6:
cout<<"Salida...";
break;
default:
cout<<"Opcion
Erronea"<<endl;
break;
}
getch();
}
}
83
ShellSort
Esta forma de ordenación es muy parecida a la ordenación con burbuja. La diferencia es
que no es una comparación lineal, sino que trabaja con una segmentación entre los datos.
Por lo tanto es un buen método, pero no el mejor para implementarlos en grandes
arreglos.
Programa:
#include<conio.h>
#include<iostream.
h>
class Lista
{
private:
int Lista[10],N;
public:
Lista()
{
for(int
i=0;i<10;i++)
Lista[i]=0;
N=0;
}
void
ShellSort(void)
{
if(N!=0)
{
int salto,aux,i;
for(salto=6/2;
salto!=0;salto/=2)
{
for(i=salto;i<6;
i++)
if(Lista[i-
salto]<Lista[i])
{
aux=Lista[i];
Lista[i]=Lista[i-
salto];
Lista[i-
salto]=aux;
}
}
cout<<"Lista
Ordenada..."
<<endl;
return;
}
cout<<"Lista
Vacia..."<<endl;
}
void Busqueda(int
Elem)
{
if(N!=0)
{
for(int
i=0;i<N;i++)
if(Lista[i]==Elem)
{
cout<<"El
"<<Elem<<" esta en
la Lista"<<endl;
return;
}
}
cout<<"Lista
Vacia..."<<endl;
return;
}
void Insertar(int
Elem)
{
if(N<10)
{
Lista[N]=Elem;
N++;
cout<<"El
"<<Elem<<" fue
Insertado"<<endl;
return;
}
cout<<"Lista
Llena... Imposible
Insertar"<<endl;
return;
}
void Eliminar(int
Elem)
{
if(N!=0)
{
for(int
i=0;i<N;i++)
if(Lista[i]==Elem)
{
Lista[i]=0;
ShellSort();
N--;
return;
}
}
cout<<"Lista
Vacia... Imposible
Eliminar..."
<<endl;
return;
}
void Recorrido()
{
if(N!=0)
{
for(int
i=0;i<N;i++)
84
cout<<Lista[i]
<<endl;
}
cout<<"Lista
Vacia..."<<endl;
}
}tec;
main()
{
int op=0,res;
while(op!=6)
{
clrscr();
cout<<"n1)
Recorridon2)
Ordenarn3)
Busquedan4)
Insercionn5)
Eliminar un
Daton6)
Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas
hacer: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido();
break;
case 2:
tec.ShellSort();
break;
case 3:
cout<<"Que Numero
de Control deseas
buscar?"<<endl;
cin>>res;
tec.Busqueda(res);
break;
case 4:
cout<<"Que Numero
Deseas
Insertar?"<<endl;
cin>>res;
tec.Insertar(res);
break;
case 5:
cout<<"Que Numero
de Control deseas
Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
break;
case 6:
cout<<"Salida...";
break;
default:
cout<<"Opcion
Erronea"<<endl;
break;
}
getch();
}
}
85
RadixSort
Este ordenamiento se basa en los valores de los dígitos reales en las representaciones de
posiciones de los números que se ordenan. Es decir… toma un número y lo descompone
en sus unidades, decenas, centenas, etc… de esta manera va determinando las posiciones
de cada uno de ellos.
Programa:
#include <math.h>
#include <conio.h>
#include
<iostream.h>
class Lista
{
private:
int
Lista[10],Temp[10]
,Elementos,N;
public:
Lista()
{
for(int
i=0;i<10;i++)
Lista[i]=0;
N=9;
Elementos=0;
}
void Ordenar()
{
if(N!=9)
{
RadixSort(0,Elemen
tos,Lista,Temp);
RadixSort(1,Elemen
tos,Temp,Lista);
RadixSort(2,Elemen
tos,Lista,Temp);
RadixSort(3,Elemen
tos,Temp,Lista);
cout<<"Lista
Ordenada..."
<<endl;
return;
}
cout<<"Lista
Vacia..."<<endl;
}
void RadixSort
(int byte, int N,
int *fuente, int
*dest)
{
int cont[256];
int ind[256];
int i;
memset(cont,0,size
of(cont));
for(i=0;i<10;i++)
cont[((fuente[i])
>>(byte*8))&0xff]
++;
ind[0]=0;
for(i=1;i<256;i++)
ind[i]=ind[i-
1]+cont[i-1];
for(i=0;i<10;i++)
dest[ind[((fuente[
i])>>(byte*8))&0xf
f]++]=fuente[i];
}
void Busqueda(int
Elem)
{
if(N!=9)
{
for(int
i=0;i<N;i++)
if(Lista[i]==Elem)
{
cout<<"El
"<<Elem<<" esta en
la Lista"<<endl;
return;
}
}
cout<<"Lista
Vacia..."<<endl;
return;
}
void Insertar(int
Elem)
{
if(N!=-1)
{
Elementos++;
Lista[N]=Elem;
N--;
cout<<"El
"<<Elem<<" fue
Insertado"<<endl;
return;
}
cout<<"Lista
Llena... Imposible
Insertar"<<endl;
return;
}
void Eliminar(int
Elem)
{
if(N!=9)
{
for(int
i=0;i<N;i++)
if(Lista[i]==Elem)
{
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++
Estructura de datos c++

Mais conteúdo relacionado

Mais procurados

Jflambert lyada - ayudantia matematicas discretas
Jflambert   lyada - ayudantia matematicas discretasJflambert   lyada - ayudantia matematicas discretas
Jflambert lyada - ayudantia matematicas discretas
Francisco Lambert Obediente
 

Mais procurados (16)

Op
OpOp
Op
 
Sistema operativo de tiempo real
Sistema operativo de tiempo realSistema operativo de tiempo real
Sistema operativo de tiempo real
 
Segmentación de cauce
Segmentación de cauceSegmentación de cauce
Segmentación de cauce
 
Pram
PramPram
Pram
 
Trabajo colaborativo 2
Trabajo colaborativo 2Trabajo colaborativo 2
Trabajo colaborativo 2
 
Socket o zocalo de procesador
Socket o zocalo de procesadorSocket o zocalo de procesador
Socket o zocalo de procesador
 
Arquitectura en pipeline
Arquitectura en pipelineArquitectura en pipeline
Arquitectura en pipeline
 
Introduccion a la computación paralela
Introduccion a la computación paralelaIntroduccion a la computación paralela
Introduccion a la computación paralela
 
Arquitectura verificar
Arquitectura verificarArquitectura verificar
Arquitectura verificar
 
Sincronización entre procesos
Sincronización entre procesosSincronización entre procesos
Sincronización entre procesos
 
Capítulo 18 (Técnicas de control de la concurrencia)
Capítulo 18 (Técnicas de control de la concurrencia)Capítulo 18 (Técnicas de control de la concurrencia)
Capítulo 18 (Técnicas de control de la concurrencia)
 
Informe técnico Unidad 7 Análisis de algoritmos (Rubí Veronica)
Informe técnico Unidad 7 Análisis de algoritmos (Rubí Veronica)Informe técnico Unidad 7 Análisis de algoritmos (Rubí Veronica)
Informe técnico Unidad 7 Análisis de algoritmos (Rubí Veronica)
 
Jflambert lyada - ayudantia matematicas discretas
Jflambert   lyada - ayudantia matematicas discretasJflambert   lyada - ayudantia matematicas discretas
Jflambert lyada - ayudantia matematicas discretas
 
Curso MATLAB
Curso MATLABCurso MATLAB
Curso MATLAB
 
Administración de memoria en java
Administración de memoria en javaAdministración de memoria en java
Administración de memoria en java
 
Introducción a la Computacion paralela
Introducción a la Computacion paralelaIntroducción a la Computacion paralela
Introducción a la Computacion paralela
 

Semelhante a Estructura de datos c++

Castaño y navarro
Castaño y navarroCastaño y navarro
Castaño y navarro
kathenavarro
 
Castaño y navarro
Castaño y navarroCastaño y navarro
Castaño y navarro
kathenavarro
 
Castaño y navarro
Castaño y navarroCastaño y navarro
Castaño y navarro
kathenavarro
 
Segunda unidas open suse
Segunda unidas open suseSegunda unidas open suse
Segunda unidas open suse
Miguel Magaña
 
Análisis de algoritmo
Análisis de algoritmoAnálisis de algoritmo
Análisis de algoritmo
Gaston Demundo
 
tercera unidad :3
tercera unidad :3tercera unidad :3
tercera unidad :3
irisdelc
 
TALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdf
TALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdfTALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdf
TALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdf
edepisabellafernande
 

Semelhante a Estructura de datos c++ (20)

Castaño y navarro
Castaño y navarroCastaño y navarro
Castaño y navarro
 
Taller 18
Taller 18Taller 18
Taller 18
 
Castaño y navarro
Castaño y navarroCastaño y navarro
Castaño y navarro
 
Castaño y navarro
Castaño y navarroCastaño y navarro
Castaño y navarro
 
Tc2 paso3
Tc2 paso3Tc2 paso3
Tc2 paso3
 
Gestion de memoria en tiempo de ejecucion
Gestion de memoria en tiempo de ejecucionGestion de memoria en tiempo de ejecucion
Gestion de memoria en tiempo de ejecucion
 
Memoria dinamica
Memoria dinamicaMemoria dinamica
Memoria dinamica
 
Segunda unidas open suse
Segunda unidas open suseSegunda unidas open suse
Segunda unidas open suse
 
Algoritmos
AlgoritmosAlgoritmos
Algoritmos
 
Unidad 7
Unidad 7Unidad 7
Unidad 7
 
Arquitectura de una computadora
Arquitectura de una computadoraArquitectura de una computadora
Arquitectura de una computadora
 
Unidad 7
Unidad 7Unidad 7
Unidad 7
 
Unidad 7
Unidad 7Unidad 7
Unidad 7
 
Análisis de algoritmo
Análisis de algoritmoAnálisis de algoritmo
Análisis de algoritmo
 
Opensuse2
Opensuse2Opensuse2
Opensuse2
 
analisis de los algoritmos
analisis de los algoritmosanalisis de los algoritmos
analisis de los algoritmos
 
Diagrama de bloque procesador intel
Diagrama de bloque procesador intelDiagrama de bloque procesador intel
Diagrama de bloque procesador intel
 
tercera unidad :3
tercera unidad :3tercera unidad :3
tercera unidad :3
 
TALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdf
TALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdfTALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdf
TALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdf
 
TALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdf
TALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdfTALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdf
TALLER DE TECNOLOGIA GRUPO 6, SEGUNDO PERIODO 10-2..docx.pdf
 

Estructura de datos c++

  • 1.
  • 2. INDICE ESTRUCTURA DE DATOS 1. Análisis de algoritmos.………………………………………………………………… 1 2. Manejo de Memoria……………………………………………………………………. 3 3. Estructura de Datos…………………………………………………………………….. 6 3.1 Pilas……………………………………………………………………………………….. 6 3.2 Colas……………………………………………………………………………………… 14 3.3 Listas Enlazadas……………………………………………………………………… 26 3.4 Listas Circulares……………………………………………………………………… 42 3.5 Listas Dobles………………………………………………………………………….. 53 4. Recursividad………………………………………………………………………………… 61 5. Árboles……………………………………………………………………………………….. 63 5.1 Arboles Binarios……………………………………………………………………… 63 5.2 Árboles en Montón………………………………………………………………… 73 6. Ordenamientos Internos………………………………………………………………. 81 7. Ordenamientos Externos……………………………………………………………… 89 8. Búsquedas………………………………………………………………………………….. 94 9. GRAFOS……………………………………………………………………………………... 106
  • 3. 1 ESTRUCTURA DE DATOS UNIDAD 1: Análisis de Algoritmos Concepto Complejidad Algoritmos La resolución práctica de un problema exige por una parte un algoritmo o método de resolución y por otra un programa o codificación de aquel en un ordenador real. Ambos componentes tienen su importancia, pero la del algoritmo es absolutamente esencial, mientras que la codificación puede muchas veces pasar a nivel de anécdota. A efectos prácticos o ingenieriles, nos deben preocupar los recursos físicos necesarios para que un programa se ejecute. Aunque puede haber muchos parámetros, los más usuales son el tiempo de ejecución y la cantidad de memoria (espacio). Ocurre con frecuencia que ambos parámetros están fijados por otras razones y se plantea la pregunta inversa: ¿cuál es el tamaño del mayor problema que puedo resolver en T segundos y/o con M bytes de memoria? En lo que sigue nos centramos casi siempre en el parámetro tiempo de ejecución, si bien las ideas desarrolladas son fácilmente aplicables a otro tipo de recursos. Para cada problema determinaremos una medida N de su tamaño (por número de datos) e intentaremos hallar respuestas en función de dicho N. El concepto exacto que mide N depende de la naturaleza del problema. Así, para un vector se suele utilizar como N su longitud; para una matriz, el número de elementos que la componen; para un grafo, puede ser el número de nodos (a veces es más importante considerar el número de arcos, dependiendo del tipo de problema a resolver), en un archivo se suele usar el número de registros, etc. Es imposible dar una regla general, pues cada problema tiene su propia lógica de coste. Tiempo de Ejecución Una medida que suele ser útil conocer es el tiempo de ejecución de un programa en función de N, lo que denominaremos T(N). Esta función se puede medir físicamente (ejecutando el programa, reloj en mano), o calcularse sobre el código contando instrucciones a ejecutar y multiplicando por el tiempo requerido por cada instrucción. Así, un trozo sencillo de programa como: S1; for (int i= 0; i < N; i++) S2;
  • 4. 2 Requiere T(N)= t1 + t2*N Siendo t1 el tiempo que lleve ejecutar la serie “S1” de sentencias, y t2 el que lleve la serie “S2”. Prácticamente todos los programas reales incluyen alguna sentencia condicional, haciendo que las sentencias efectivamente ejecutadas dependan de los datos concretos que se le presenten. Esto hace que más que un valor T(N) debamos hablar de un rango de valores Tmin(N) ⇐⇐⇐⇐ T(N) ⇐⇐⇐⇐ Tmax(N) Los extremos son habitualmente conocidos como “caso peor” y “caso mejor”. Entre ambos se hallara algún “caso promedio” o más frecuente. Cualquier fórmula T(N) incluye referencias al parámetro N y a una serie de constantes “Ti” que dependen de factores externos al algoritmo como pueden ser la calidad del código generado por el compilador y la velocidad de ejecución de instrucciones del ordenador que lo ejecuta. Dado que es fácil cambiar de compilador y que la potencia de los ordenadores crece a un ritmo vertiginoso (en la actualidad, se duplica anualmente), intentaremos analizar los algoritmos con algún nivel de independencia de estos factores; es decir, buscaremos estimaciones generales ampliamente válidas.
  • 5. 3 UNIDAD 2: Manejo de Memoria Memoria 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. 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: • Los objetos correspondientes a procedimientos o funciones recursivas, ya que en tiempo de compilación no se sabe el número de variables que serán necesarias. • Las estructuras dinámicas de datos tales como listas, árboles, etc. ya que el número de elementos que las forman no es conocido hasta que el programa se ejecuta. Las técnicas de asignación de memoria estática son sencillas. A partir de una posición señalada por un puntero de referencia se aloja el objeto X, y se avanza el puntero tantos bytes como sean necesarios para almacenar el objeto X. 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. Dentro de cada registro de activación las variables locales se organizan secuencialmente. Existe un solo registro de activación para cada procedimiento y por tanto no están permitidas las llamadas recursivas. El proceso que se sigue cuando un procedimiento p llama a otra q es el siguiente: 1. p evalúa los parámetros de llamada, en caso de que se trate de expresiones complejas, usando para ello una zona de memoria temporal para el almacenamiento intermedio. Por ejemplos, sí la llamada a q es q((3*5)+(2*2),7) las operaciones previas a la llamada propiamente dicha en código máquina han de realizarse sobre alguna zona de memoria temporal. (En algún momento debe haber una zona de memoria que contenga el valor intermedio 15, y el valor intermedio 4 para sumarlos a continuación). En caso de utilización de memoria estática ésta zona de temporales puede ser común a todo el programa, ya que su tamaño puede deducirse en tiempo de compilación.
  • 6. 4 2. q inicializa sus variables y comienza su ejecución. Dado que las variables están permanentemente en memoria es fácil implementar la propiedad de que conserven o no su contenido para cada nueva llamada Memoria Dinámica ¿Qué es la memoria dinámica? Supongamos que nuestro programa debe manipular estructuras de datos de longitud desconocida. Un ejemplo simple podría ser el de un programa que lee las líneas de un archivo y las ordena. Por tanto, deberemos leer un número indeterminado de líneas, y tras leer la última, ordenarlas. Una manera de manejar ese ``número indeterminado'', sería declarar una constante MAX_LINEAS, darle un valor vergonzosamente grande, y declarar un array de tamaño MAX_LINEAS. Esto, obviamente, es muy ineficiente (y feo). Nuestro programa no sólo quedaría limitado por ese valor máximo, sino que además gastaría esa enorme cantidad de memoria para procesar hasta el más pequeño de los ficheros. La solución consiste en utilizar memoria dinámica. La memoria dinámica es un espacio de almacenamiento que se solicita en tiempo de ejecución. De esa manera, a medida que el proceso va necesitando espacio para más líneas, va solicitando más memoria al sistema operativo para guardarlas. El medio para manejar la memoria que otorga el sistema operativo, es el puntero, puesto que no podemos saber en tiempo de compilación dónde nos dará huecos el sistema operativo (en la memoria de nuestro PC). Memoria Dinámica. Sobre el tratamiento de memoria, GLib dispone de una serie de instrucciones que sustituyen a las ya conocidas por todos malloc, free, etc. y, siguiendo con el modo de llamar a las funciones en GLib, las funciones que sustituyen a las ya mencionadas son g_malloc y g_free. Reserva de memoria. La función g_malloc posibilita la reserva de una zona de memoria, con un número de bytes que le pasemos como parámetro. Además, también existe una función similar llamada g_malloc0 que, no sólo reserva una zona de memoria, sino que, además, llena esa zona de memoria con ceros, lo cual nos puede beneficiar si se necesita un zona de memoria totalmente limpia. gpointer g_malloc (gulong numero_de_bytes ); gpointer g_malloc0 (gulong numero_de_bytes ); Existe otro conjunto de funciones que nos permiten reservar memoria de una forma parecida a cómo se hace en los lenguajes orientados a objetos.
  • 7. 5 Liberación de memoria. Cuando se hace una reserva de memoria con g_malloc y, en un momento dado, el uso de esa memoria no tiene sentido, es el momento de liberar esa memoria. Y el sustituto de free es g_free que, básicamente, funciona igual que la anteriormente mencionada. void g_free (gpointer memoria_reservada ); Realojamiento de memoria En determinadas ocasiones, sobre todo cuando se utilizan estructuras de datos dinámicas, es necesario ajustar el tamaño de una zona de memoria (ya sea para hacerla más grande o más pequeña). Para eso, GLib ofrece la función g_realloc, que recibe un puntero a memoria que apunta a una región que es la que será acomodada al nuevo tamaño y devuelve el puntero a la nueva zona de memoria. El anterior puntero es liberado y no se debería utilizar más: gpointer g_realloc (gpointer memoria_reservada , gulong numero_de_bytes ); Asignación dinámica El proceso de compactación del punto anterior es una instancia particular del problema de asignación de memoria dinámica, el cual es el cómo satisfacer una necesidad de tamaño n con una lista de huecos libres. Existen muchas soluciones para el problema. El conjunto de huecos es analizado para determinar cuál hueco es el más indicado para asignarse. Las estrategias más comunes para asignar algún hueco de la tabla son: Primer ajuste: Consiste en asignar el primer hueco con capacidad suficiente. La búsqueda puede iniciar ya sea al inicio o al final del conjunto de huecos o en donde terminó la última búsqueda. La búsqueda termina al encontrar un hueco lo suficientemente grande. Mejor ajuste: Busca asignar el espacio más pequeño de los espacios con capacidad suficiente. La búsqueda se debe de realizar en toda la tabla, a menos que la tabla esté ordenada por tamaño. Esta estrategia produce el menor desperdicio de memoria posible. Peor ajuste: Asigna el hueco más grande. Una vez más, se debe de buscar en toda la tabla de huecos a menos que esté organizada por tamaño. Esta estrategia produce los huecos de sobra más grandes, los cuales pudieran ser de más uso si llegan procesos de tamaño mediano que quepan en ellos. Se ha demostrado mediante simulacros que tanto el primer y el mejor ajuste son mejores que el peor ajuste en cuanto a minimizar tanto el tiempo del almacenamiento. Ni el primer o el mejor ajuste es claramente el mejor en términos de uso de espacio, pero por lo general el primer ajuste es más rápido.
  • 8. 6 UNIDAD 3: ESTRUCTURA DATOS 3.1 PILAS LIFO Son aquellas que solo tiene 2 operaciones, Push(Inserción) y Pop(Eliminación) la cual solo se puede efectuar por un extremo llamado Top. Sin Embargo se le pueden aplicar todas las operaciones al igual que a las listas. Recorrido Ya que las pilas son LIFO(Last in - First Out) el Recorrido se hace sacando el último dato que se insertó hasta que no encuentre ningún otro. Detalle: Apuntador toma el Top, después ve si la condición cumple para efectuar un Ciclo mientras Apuntador sea diferente de Nulo, si cumple lo que hace es que despliega el contenido de la Pila(Pila[Apuntador]), después Apuntador se le resta 1. Este proceso se repite hasta que Apuntador sea igual Nulo(Cuando llega a este punto la Pila ya fue Recorrida). Algoritmo: Recorrido(Pila, Top) Apuntador ←- Top Repetir mientras Apuntador &ne; Nulo Imprimir Pila[Apuntador] Apuntador ←- Apuntador - 1 Fin del ciclo Salir Diagrama:
  • 9. 7 Corrida: Push Push es simplemente el método por el cual va agregando un Dato nuevo a la Pila tomando en cuenta la Capacidad Máxima (Max) de almacenar un dato. Detalle: Compara en un principio el Top con Max, si la condición no cumple es imposible insertar más datos a la Pila, de otra forma lo que hace es Incrementar el valor de Top, y copia el valor de Elemento en Pila[Top]. De esta forma el dato ya está insertado. Algoritmo: Push(Pila, Top, Max, Elemento) Si Top &ne; Max Top ←- Top + 1 Pila[Top] ←- Elemento Si no: Imprimir “Pila Llena” Salir Diagrama:
  • 10. 8 Corrida: Búsqueda Este método usa el recorrido para encontrar Elemento y desplegar un mensaje si la búsqueda es exitosa. Detalle: El algoritmo compara para determinar si la Pila tiene algún dato, sino simplemente desplegara Lista Vacía y saldrá. De otra manera hará un Recorrido y comparara con cada uno de los Datos de la Pila hasta encontrar el dato que desea buscar. Si lo encuentra desplegara “El Dato fue encontrado” de otra manera “El Dato no se encontró”. Algoritmo: Busqueda(Pila, Top, Elemento) Si Top &ne; Nulo Apuntador ←- Top Repetir mientras Apuntador &ne; Nulo Si Pila[Apuntador] = Elemento Imprimir “El Dato fue encontrado” y Salir Apuntador ←- Apuntador - 1 Fin del ciclo Imprimir “El Dato no se encontró” Si no: Imprimir “Pila Vacía” Salir
  • 11. 9 Diagrama: Corrida: Eliminación Este método busca un Dato dentro de la pila y lo elimina. Detalle: El algoritmo compara para determinar si la Pila tiene algún dato, sino simplemente desplegara Pila Vacía y saldrá. De otra manera hará un Recorrido y comparara con cada uno de los Datos de la Pila hasta encontrar el dato que desea eliminar, mientras hace esto copia cada uno de los datos a un arreglo Temp para cuando encuentre el Dato regresar esos valores a la Pila. Si lo encuentra desplegara “Eliminado el Dato” y le restara 1 a Top, de otra manera “El Dato no encontrado”. Algoritmo: Borrar(Pila, Temp, Top, Elemento) Si Top &ne; Nulo
  • 12. 10 Apuntador1 ←- Top Repetir mientras Apuntador1 &ne; Nulo Si Pila[Apuntador1] = Elemento Imprimir “Eliminando el Dato…” Repetir mientras Apuntador2 &ne; Nulo Pila[Apuntador1]=Temp[Apuntador2] Fin del ciclo Top ←- Top - 1 y Salir Si No: Temp[Apuntador2] ←- Pila[Apuntador1] Apuntador1 ←- Apuntador1 - 1 Apuntador2 ←- Apuntador2 + 1 Fin del ciclo Imprimir “Dato no encontrado” Si no: Imprimir “Pila Vacía” Salir Diagrama: Corrida:
  • 13. 11 #include <stdio.h> #include <conio.h> #include <string.h> #include <iomanip.h> #include <iostream.h> class Alumno { private: int Pila[10],Top,Max; char Pila1[10][10]; public: Alumno() { int i,j; char Nulo[2]=" "; Max=9; Top=-1; for(i=1;i<9;i++) { Pila[i]=0; strcpy(Pila1[i],Nulo); } } void Push(charElem[10]) { if(Top!=Max) { Top++; strcpy(Pila1[Top],Elem ); } else cout<<"Pila Llena"<<endl; } void Push(int Elem) { if(Top!=Max) { Top++; Pila[Top]=Elem; } else cout<<"Pila Llena"<<endl; } void Push(float Elem) { if(Top!=Max) { Top++; Pila[Top]=Elem; } else cout<<"Pila Llena"<<endl; } void Push(double Elem) { if(Top!=Max) { Top++; Pila[Top]=Elem; } else cout<<"Pila Llena"<<endl; } void Pop(void) { if(Top!=-1) { cout<<"Sacando el Dato: "<<Pila[Top]; Top--; } else cout<<"Pila Vacia... Imposible Eliminar"<<endl; } void Recorrido(void) { if(Top!=-1) int i; for(i=Top;i!=-1; i--) cout<<Pila[i] <<endl; else cout<<"Pila Vacia..."; } Void Busqueda(charElem [10]) { Int i; for(i=Top;i!=-1; i--) if((strcmp(Elem, Pila1[i]))==0) { cout<<"Dato "<<Pila1[i] <<" encontrado..." <<endl; return; } cout<<"Dato no encontrado..." <<endl; } Int Elem; void Busqueda(Elem) { Int i; for(i=Top;i!=-1; i--) if(Elem==Pila[i]) { cout<<"Dato "<<Pila[i] <<" encontrado..." <<endl; return; } cout<<"Dato no encontrado..." <<endl; } Float Elem; void Busqueda(Elem) { Int i; for(i=Top;i!=-1; i--) if(Elem==Pila[i]) { cout<<"Dato "<<Pila[i] <<"encontrado..." <<endl; return; } cout<<"Dato no encontrado..." <<endl; } Double Elem; void Busqueda(Elem) { Int i; for(i=Top;i!=-1; i--) if(Elem==Pila[i]) { cout<<"Dato "<<Pila[i] <<"encontrado..." <<endl;
  • 14. 12 return; } cout<<"Dato no encontrado..." <<endl; } void Borrar(charElem [10]) { char Temp[10][10]; int i=0,j=Top; if(Top==-1) { cout<<"Pila Vacia... Imposible Eliminar..."; return; } while(j!=-1) { if((strcmp(Elem, Pila1[j]))==0) { cout<<"Dato Eliminado..."; for(i--;i!= - 1;j++,i--) strcpy(Pila1[j], Temp[i]); Top--; return; } else { strcpy(Temp[i], Pila1[j]); i++; j--; } } cout<<"Dato no encontrado... Imposible Eliminar..."; return; } void Borrar(int Elem) { IntTemp[10],i=0, j=Top; if(Top==-1) { cout<<"Pila Vacia... Imposible Eliminar..."; return; } while(j!=-1) { if(Elem==Pila[j]) { cout<<"Dato Eliminado..."; for(i--;i!= - 1;j++,i--) Pila[j]=Temp[i]; Top--; return; } else { Temp[i]=Pila[j]; i++; j--; } } cout<<"Dato no encontrado... Imposible Eliminar..."; return; } Float Elem; void Borrar(Elem) { intTemp[10],i=0, j=Top; if(Top==-1) { cout<<"Pila Vacia... Imposible Eliminar..."; return; } while(j!=-1) { if(Elem==Pila[j]) { cout<<"Dato Eliminado..."; for(i--;i!= - 1;j++,i--) Pila[j]=Temp[i]; Top--; return; } else { Temp[i]=Pila[j]; i++; j--; } } cout<<"Dato no encontrado... Imposible Eliminar..."; return; } Double Elem; void Borrar(Elem) { intTemp[10],i=0, j=Top; if(Top==-1) { cout<<"Pila Vacia... Imposible Eliminar..."; return; } while(j!=-1) { if(Elem==Pila[j]) { cout<<"Dato Eliminado..."; for(i--;i!= - 1;j++,i--) Pila[j]=Temp[i]; Top--; return; } else { Temp[i]=Pila[j]; i++; j--; } }
  • 15. 13 cout<<"Dato no encontrado... Imposible Eliminar..."; return; } }tec; main() { int res,op=0; while(op!=6) { clrscr(); cout<<"n1) Recorridon2) Busquedan3) Pushn4) Popn5) Eliminar un Daton6) Salir"<<endl; gotoxy(1,1); cout<<"Que deseas hacer?: "; cin>>op; gotoxy(1,10); switch (op) { case 1: tec.Recorrido(); break; case 2: cout<<"Que Numero deseas buscar?"<<endl; cin>>res; tec.Busqueda(res); break; case 3: cout<<"Que Numero quieres Insertar?"<<endl; cin>>res; tec.Push(res); break; case 4: tec.Pop(); break; case 5: cout<<"Que Numero deseas eliminar?"<<endl; cin>>res; tec.Borrar(res); break; case 6: cout<<"Salida..."; break; default: cout<<"Opcion Erronea"<<endl; break; } getch(); } }
  • 16. 14 3.2 Colas FIFO 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 Ya que las colas son FIFO(First in - First Out) el Recorrido se hace sacando el primer dato que se insertó 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 cuándo 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
  • 17. 15 Diagrama: Corrida: Push 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 esté 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.
  • 18. 16 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 Diagrama: Corrida:
  • 19. 17 Pop 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 está 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:
  • 20. 18 Corrida: Búsqueda 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
  • 21. 19 Diagrama: Corrida: Eliminació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.
  • 23. 21 #include <stdio.h> #include <conio.h> #include <string.h> #include <iomanip.h> #include <iostream.h> class Alumno { private: intCola[10],Frente,Fin al,Max; char Cola1[10][10]; public: Alumno() { int i,j; char Nulo[2]=" "; Frente=-1; Final=-1; Max=9; for(i=1;i<9;i++) { Cola[i]=0; strcpy(Cola1[i],Nulo); } } void Push(charElem[10]) { if((Frente==0&&Final== 9)||(Frente==(Final+1) )) { cout<<"Cola Llena"<<endl; return; } if(Frente==-1) { Frente=0; Final=0; } else if(Final==Max) Final=0; else Final++; strcpy(Cola1[Final],El em); } void Push(int Elem) { if((Frente==0&&Final== 9)||(Frente==(Final+1) )) { cout<<"Cola Llena"<<endl; return; } if(Frente==-1) { Frente=0; Final=0; } else if(Final==Max) Final=0; else Final++; Cola[Final]=Elem; } void Push(float Elem) { if((Frente==0&&Final== 9)||(Frente==(Final+1) )) { cout<<"Cola Llena"<<endl; return; } if(Frente==-1) { Frente=0; Final=0; } else if(Final==Max) Final=0; else Final++; Cola[Final]=Elem; } void Push(double Elem) { if((Frente==0&&Final== 9)||(Frente==(Final+1) )) { cout<<"Cola Llena"<<endl; return; } if(Frente==-1) { Frente=0; Final=0; } else if(Final==Max) Final=0; else Final++; Cola[Final]=Elem; } void Pop(void) { if(Frente!=-1) { cout<<"Elmininado el Dato: "<<Cola[Frente]; if(Frente==Final) { Frente=-1; Final=-1; } else if(Frente==Max) Frente=0; else Frente++; } else cout<<"Cola Vacia... Imposible Eliminar"<<endl; } void Recorrido(void) { int i; if(Frente!=-1) { if(Frente<=Final) for(i=Frente;i<=Final; i++) cout<<Cola[i]<<endl; else if(Frente>Final) for(i=Frente;i!=Final; i++) { if(i>Max)
  • 24. 22 i=0; cout<<Cola[i]<<endl; } } else cout<<"Cola Vacia..."; } void Busqueda(char Elem[10]) { int i; if(Frente!=-1) { if(Frente<=Final) for(i=Frente;i<=Final; i++) if((strcmp(Elem,Cola1[ i]))==0) { cout<<"Dato "<<Cola1[i]<<" encontrado..."<<endl; return; } else if(Frente>Final) for(i=Frente;i!=Final; i++) { if(i>Max) i=0; if((strcmp(Elem,Cola1[ i]))==0) { cout<<"Dato "<<Cola1[i]<<" encontrado..."<<endl; return; } } } else cout<<"Dato no encontrado..."; } void Busqueda(int Elem) { int i; if(Frente!=-1) { if(Frente<=Final) for(i=Frente;i<=Final; i++) if(Elem==Cola[i]) { cout<<"Dato "<<Cola[i]<<" encontrado..."<<endl; return; } else if(Frente>Final) for(i=Frente;i!=Final; i++) { if(i>Max) i=0; if(Elem==Cola[i]) { cout<<"Dato "<<Cola[i]<<" encontrado..."<<endl; return; } } } else cout<<"Dato no encontrado..."; } void Busqueda(float Elem) { int i; if(Frente!=-1) { if(Frente<=Final) for(i=Frente;i<=Final; i++) if(Elem==Cola[i]) { cout<<"Dato "<<Cola[i]<<" encontrado..."<<endl; return; } else if(Frente>Final) for(i=Frente;i!=Final; i++) { if(i>Max) i=0; if(Elem==Cola[i]) { cout<<"Dato "<<Cola[i]<<" encontrado..."<<endl; return; } } } else cout<<"Dato no encontrado..."; } void Busqueda(double Elem) { int i; if(Frente!=-1) { if(Frente<=Final) for(i=Frente;i<=Final; i++) if(Elem==Cola[i]) { cout<<"Dato "<<Cola[i]<<" encontrado..."<<endl; return; } else if(Frente>Final) for(i=Frente;i!=Final; i++) { if(i>Max) i=0; if(Elem==Cola[i]) { cout<<"Dato "<<Cola[i]<<"
  • 25. 23 encontrado..."<<endl; return; } } } else cout<<"Dato no encontrado..."; } void Borrar(char Elem[10]) { char Temp[10][10]; int i,j; if(Frente!=-1) { if(Frente<=Final) for(j=0,i=Frente;i<=Fi nal;i++,j++) { if((strcmp(Elem,Cola1[ i]))==0) { cout<<"Eliminado el Dato "<<Cola1[i]<<endl; if(Frente==Final) { Frente=-1; Final=-1; return; } else if(Frente==Max) Frente=0; else Frente++; for(j--,i=Frente;j!=- 1;i++,j--) strcpy(Cola1[i],Temp[j ]); return; } strcpy(Temp[j],Cola1[i ]); } else if(Frente>Final) for(j=0,i=Frente;i!=Fi nal;i++,j++) { if(i>Max) i=0; if((strcmp(Elem,Cola1[ i]))==0) { cout<<"Eliminado el Dato "<<Cola1[i]<<endl; if(Frente==Max) Frente=0; else Frente++; for(j--,i=Frente;j!=- 1;i++,j--) { if(i>Max) i=0; strcpy(Cola1[i],Temp[j ]); } return; } strcpy(Temp[j],Cola1[i ]); } cout<<"Dato no Encontrado..."; } else cout<<"Cola Vacia... Imposible Eliminar..."; } void Borrar(int Elem) { int Temp[10],i,j; if(Frente!=-1) { if(Frente<=Final) for(j=0,i=Frente;i<=Fi nal;i++,j++) { if(Elem==Cola[i]) { cout<<"Eliminado el Dato "<<Cola[i]<<endl; if(Frente==Final) { Frente=-1; Final=-1; return; } else if(Frente==Max) Frente=0; else Frente++; for(j--,i=Frente;j!=- 1;i++,j--) Cola[i]=Temp[j]; return; } Temp[j]=Cola[i]; } else if(Frente>Final) for(j=0,i=Frente;i!=Fi nal;i++,j++) { if(i>Max) i=0; if(Elem==Cola[i]) { cout<<"Eliminado el Dato "<<Cola[i]<<endl; if(Frente==Max) Frente=0; else Frente++; for(j--,i=Frente;j!=- 1;i++,j--) { if(i>Max) i=0; Cola[i]=Temp[j]; } return; } Temp[j]=Cola[i]; } cout<<"Dato no Encontrado..."; }
  • 26. 24 else cout<<"Cola Vacia... Imposible Eliminar..."; } void Borrar(float Elem) { int Temp[10],i,j; if(Frente!=-1) { if(Frente<=Final) for(j=0,i=Frente;i<=Fi nal;i++,j++) { if(Elem==Cola[i]) { cout<<"Eliminado el Dato "<<Cola[i]<<endl; if(Frente==Final) { Frente=-1; Final=-1; return; } else if(Frente==Max) Frente=0; else Frente++; for(j--,i=Frente;j!=- 1;i++,j--) Cola[i]=Temp[j]; return; } Temp[j]=Cola[i]; } else if(Frente>Final) for(j=0,i=Frente;i!=Fi nal;i++,j++) { if(i>Max) i=0; if(Elem==Cola[i]) { cout<<"Eliminado el Dato "<<Cola[i]<<endl; if(Frente==Max) Frente=0; else Frente++; for(j--,i=Frente;j!=- 1;i++,j--) { if(i>Max) i=0; Cola[i]=Temp[j]; } return; } Temp[j]=Cola[i]; } cout<<"Dato no Encontrado..."; } else cout<<"Cola Vacia... Imposible Eliminar..."; } void Borrar(double Elem) { int Temp[10],i,j; if(Frente!=-1) { if(Frente<=Final) for(j=0,i=Frente;i<=Fi nal;i++,j++) { if(Elem==Cola[i]) { cout<<"Eliminado el Dato "<<Cola[i]<<endl; if(Frente==Final) { Frente=-1; Final=-1; return; } else if(Frente==Max) Frente=0; else Frente++; for(j--,i=Frente;j!=- 1;i++,j--) Cola[i]=Temp[j]; return; } Temp[j]=Cola[i]; } else if(Frente>Final) for(j=0,i=Frente;i!=Fi nal;i++,j++) { if(i>Max) i=0; if(Elem==Cola[i]) { cout<<"Eliminado el Dato "<<Cola[i]<<endl; if(Frente==Max) Frente=0; else Frente++; for(j--,i=Frente;j!=- 1;i++,j--) { if(i>Max) i=0; Cola[i]=Temp[j]; } return; } Temp[j]=Cola[i]; } cout<<"Dato no Encontrado..."; } else cout<<"Cola Vacia... Imposible Eliminar..."; } }tec; main() { int res,op=0; while(op!=6) { clrscr(); cout<<"n1) Recorridon2)
  • 27. 25 Busquedan3) Pushn4) Popn5) Eliminar un Daton6) Salir"<<endl; gotoxy(1,1); cout<<"Que deseas hacer?: "; cin>>op; gotoxy(1,10); switch (op) { case 1: tec.Recorrido(); break; case 2: cout<<"Que Numero deseas buscar?"<<endl; cin>>res; tec.Busqueda(res); break; case 3: cout<<"Que Numero quieres Insertar?"<<endl; cin>>res; tec.Push(res); break; case 4: tec.Pop(); break; case 5: cout<<"Que Numero deseas eliminar?"<<endl; cin>>res; tec.Borrar(res); break; case 6: cout<<"Salida..."; break; default: cout<<"Opcion Erronea"<<endl; break; } getch(); } }
  • 28. 26 3.3 Listas Enlazadas Recorrido Recorrido simplemente despliega los datos almacenados en el arreglo Info, con ayuda de un segundo arreglo llamado Índice el cual guarda el orden en el que encuentran enlazados cada uno de los datos. Explicación: Apuntador toma el valor de Inicio, después ve si la condición cumple para efectuar un Ciclo mientras Apuntador sea diferente de 0, si cumple lo que hace es que despliega la Info[Apuntador], después Apuntador toma el valor de Indice[Apuntador] (El cual nos indica el siguiente nodo que sigue en la lista) y hace esto hasta que Apuntador sea igual a 0 (Cuando llega a este punto a llegado al fin de la Lista Enlazada). Algoritmo: Recorrido(Inicio, Info, Indice) Apuntador ←- Inicio Repetir mientras Apuntador ≠ Nill Imprimir Info[Apuntador] Apuntador ←- Indice[Apuntador] Fin del ciclo Salir Diagrama:
  • 29. 27 Programa: #include <conio.h> #include <iostream.h> void Recorrido(char Info[8][2],int Indice[8],int Inicio,int Disp); void main() { char Info[8][2]={{"G"}, {"I"},{" "},{"T"},{"O"},{"A "}, {" "},{"T"}}; int Indice[8]={5,7,6,1 ,-999,3,-999,4}; int Inicio=0,Disp=2; cout<<"El Recorrido es:n"; Recorrido(Info,Ind ice,Inicio,Disp); getch(); } void Recorrido(char Info[8][2],int Indice[8],int Inicio,int Disp) { int Apuntador=Inicio; while(Apuntador!=- 999) { cout<<Info[Apuntad or]; Apuntador=Indice[A puntador]; } } Corrida: Búsqueda La Búsqueda su objetivo es encontrar un dato en el arreglo Info, si lo encuentra lo desplegara en la pantalla, si no lo encuentra no desplegara nada ya que el dato no se encuentra en el arreglo Info.
  • 30. 28 Explicación: Apuntador toma el valor de Inicio, después ve si la condición cumple para efectuar un Ciclo mientras Apuntador sea diferente de 0, si cumple lo que hace a continuación es la comparación de Elemento (El dato que vamos a buscar) con Info[Apuntador], cuando lo encuentre lo despliega y sale del método. Si no, regresa el valor de Apuntador para así saber que no se encontró el dato. Algoritmo: Recorrido(Inicio, Info, Indice, Elemento) Apuntador ←- Inicio Repetir mientras Apuntador ≠ Nill Si Elemento = Info[Apuntador] entonces: Imprimir Info[Apuntador] Regresa Apuntador Apuntador ←- Indice[Apuntador] Fin del ciclo Regresar Apuntador Diagrama:
  • 31. 29 Programa: #include <conio.h> #include <iostream.h> int Busqueda(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento); void main() { int Info[8]={12,10,0,9 ,5,3,0,20}; int Indice[8]={5,7,6,1 ,-999,3,-999,4}; int Inicio=0,Disp=2,El emento,Res; cout<<"Que Numero deseas buscar?"; cin>>Elemento; Res=Busqueda(Info, Indice,Inicio,Disp ,Elemento); if(Res==-999) cout<<"Dato No Encontrado..."; getch(); } int Busqueda(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento) { int Apuntador=Inicio; while(Apuntador!=- 999) { if(Elemento==Info[ Apuntador]) { cout<<"Numero "<<Info[Apuntador] <<" encontrado..."; return Apuntador; } Apuntador=Indice[A puntador]; } return Apuntador; } Corrida:
  • 32. 30 Inserción al Principio La Inserción al Principio básicamente busca si existe algún lugar disponible en el arreglo Info y lo agrega como primer Nodo si es que es posible. Explicación: Hace una comparación para ver si es posible insertar otro Elemento al arreglo Info, para esto checa si Disp es Diferente de Nulo. Si no cumple con la condición se desplegar “Sobre Carga” ya que no se puede insertar un Nuevo Elemento. Si es cierto Apuntador toma el valor de Inicio, Disp cambia a Indice[Disp] ya que el primer Disp tomara el valor del Nuevo Elemento, después de esto solo copia la información de Elemento al arreglo Info en la posición que guarda Apuntador, Indice[Apuntador] toma el valor de Inicio y finalmente Inicio toma el valor de Apuntador. Algoritmo: InsPr(Inicio, Disp, Info, Indice, Elemento) Si Disp ≠ Nill entonces: Apuntador ←- Disp Disp ←- Indice[Disp] Info[Apuntador] ←- Elemento Indice[Apuntador] ←- Inicio Inicio ←- Apuntador Si no: Imprimir “Sobre Carga” Salir Diagrama:
  • 33. 31 Programa: #include <conio.h> #include <iostream.h> void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp); void InsPr(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento); void main() { int Info[8]={12,10,0,9 ,5,3,0,20}; int Indice[8]={5,7,6,1 ,-999,3,-999,4}; int Inicio=0,Disp=2,El emento,Res; cout<<"Lista Originaln"; Recorrido(Info,Ind ice,Inicio,Disp); cout<<"Que Numero deseas Insertar?"; cin>>Elemento; InsPr(Info,Indice, Inicio,Disp,Elemen to); getch(); } void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp) { int Apuntador=Inicio; while(Apuntador!=- 999) { cout<<Info[Apuntad or]<<endl; Apuntador=Indice[A puntador]; } } void InsPr(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento) { if(Disp!=-999) { int Apuntador=Disp; Disp=Indice[Disp]; Info[Apuntador]=El emento; Indice[Apuntador]= Inicio; Inicio=Apuntador; Recorrido(Info,Ind ice,Inicio,Disp); } else cout<<"Overflow... "; }
  • 34. 32 CORRIDA: Inserción después de Un Nodo Determinado La Inserción después de un Nodo Determinado básicamente hace lo mismo que la inserción al principio, la única diferencia es que este recibe la posición del nodo en la que será Insertada. Este Algoritmo se usa para Inserción Ordenada que más adelante explicaremos. Explicación: Primero confirma que sea posible insertar el Dato, si no es posible solo desplegara “Sobre Carga”. Si es posible insertar un dato nuevo lo posiciona en la primer posición Disponible en el arreglo Info, después compara la Nueva Posición (Npos) que le mandamos con Nill si cumple la condición el dato es insertado en la primer posición, de otra forma se posicionara en la posición que guarde Npos. Algoritmo: InsNd(Inicio, Disp, Info, Indice, Elemento, Npos) Si Disp ≠ Nill entonces: Apuntador ←- Disp Disp ←- Indice[Disp] Info [Apuntador] ←- Elemento Si Npos = Nill entonces: Indice[Apuntador] ←- Inicio Inicio ←- Apuntador Si no: Indice[Apuntador] ←- Indice[Npos] Indice[Npos] ←- Apuntador Si no: Imprimir “Sobre Carga” Salir
  • 35. 33 Inserción Ordenada La Inserción Ordenada busca la posición en donde será Insertado el Elemento y la posición anterior donde será Insertado, después de encontrar la posición en la que será Insertado el Elemento nos regresa ese valor y lo mandamos al método de la Inserción después de un Nodo. Explicación: En esta ocasión usaremos dos variables para determinar la posición deseada, comparamos si Inicio es igual a Nill ó si Elemento es menor al dato que se encuentra en Info[Inicio], si alguna de las dos cumple regresamos Nill, de esta manera Indicamos que el Elemento será el primero de todo el Arreglo Info, si no es así Temp tomara el valor de Inicio y Temp2 de la posición que le sigue a Inicio. Hace un ciclo hasta encontrar la posición en donde se insertara el Nuevo Elemento y va moviéndose de posición con las variables Temp y Temp2 para así determinar qué posición debe de regresar. Algoritmo: InsOrd(Inicio, Info, Indice, Elemento) Si Inicio = Nill ó Elemento < Info[Inicio] entonces: Regresar Nill Temp ←- Inicio Temp2 ←- Indice[Inicio] Repetir mientras Temp2 ≠ Nill Si Elemento < Info[Temp2] Regresar Temp Temp ←- Temp2 Temp2 ←- Indice[Temp2] Regresar Temp Diagrama:
  • 36. 34 Programa: #include <conio.h> #include <iostream.h> int InsOrd(int Info[8],int Indice[8],int Inicio,int Elemento); void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp); void InsNd(int Info[8],int Indice[8],int Inicio,int Disp, int Elemento, int Npos); void main() { int Info[8]={12,10,0,9 ,5,3,0,20}; int Indice[8]={5,7,6,1 ,-999,3,-999,4}; int Inicio=0,Disp=2,El emento,Res; cout<<"Lista Originaln"; Recorrido(Info,Ind ice,Inicio,Disp); cout<<"Que Numero deseas Insertar?"; cin>>Elemento; Res=InsOrd(Info,In dice,Inicio,Elemen to); InsNd(Info,Indice, Inicio,Disp,Elemen to,Res); getch(); } void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp) { int Apuntador=Inicio; while(Apuntador!=- 999) { cout<<Info[Apuntad or]<<endl; Apuntador=Indice[A puntador]; } } void InsNd(int Info[8],int Indice[8],int Inicio,int Disp, int Elemento, int Npos) { if(Disp!=-999) { int Apuntador=Disp; Disp=Indice[Disp]; Info[Apuntador]=El emento; if(Npos==-999) { Indice[Apuntador]= Inicio; Inicio=Apuntador; } else { Indice[Apuntador]= Indice[Npos]; Indice[Npos]=Apunt ador; } Recorrido(Info,Ind ice,Inicio,Disp); } else cout<<"Overflow... "; } int InsOrd(int Info[8],int Indice[8],int Inicio,int Elemento) { int Temp=- 999,Temp2; if(Inicio==Temp||E lemento<Info[Inici o]) return Temp; Temp=Inicio; Temp2=Indice[Inici o]; while(Temp2!=-999) { if(Elemento<Info[T emp2]) return Temp; Temp=Temp2; Temp2=Indice[Temp2 ]; } return Temp; }
  • 37. 35 CORRIDA: Eliminación por Búsqueda La Eliminación simplemente cambia los nodos para que el dato que se desea eliminar sea el primer disponible, de esta forma ya no estará en el Arreglo de Info. Explicación: Lo primero que hace es ver si existe algún dato en la lista para eliminar, si Inicio es igual a Nill entonces solo desplegara “Imposible Eliminar”. De otra formas cambiar de Posición en Posición hasta encontrar el Elemento que sea desea Eliminar con ayudar de dos variables que guardan la Posición actual y la anterior en donde se encuentre el dato. Ya que lo encuentra cambia ese dato como la primera posición Disponible y lo apunta al siguiente nodo disponible. Si no encuentra el dato simplemente desplegara “Dato no encontrado” Algoritmo: EliBusq(Inicio, Info, Indice, Elemento) Temp ←- Inicio Si Temp = Nill Imprimir “Lista Vacia… Imposible Eliminar” y Retornar Repetir mientras Temp ≠ Nill Si Elemento = Info[Temp] entonces: Si Temp = Inicio entonces: Inicio ←- Indice[Inicio] Si no: Indice[Temp2] ←- Indice[Temp] Indice[Temp] ß Disp Disp ←- Temp Recorrido(Inicio, Info, Indice) y Retornar Si no: Temp2 ←- Temp Temp ←- Indice[Temp] Imprimir “Dato no encontrado… Imposible Eliminar” y Retornar
  • 38. 36 Diagrama Programa: #include <conio.h> #include <iostream.h> void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp); void EliBusq(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento); void main() { int Info[8]={12,10,0,9 ,5,3,0,20}; int Indice[8]={5,7,6,1 ,-999,3,-999,4}; int Inicio=0,Disp=2,El emento,Res; cout<<"Lista Originaln"; Recorrido(Info,Ind ice,Inicio,Disp); cout<<"Que Numero deseas Eliminar?"; cin>>Elemento; EliBusq(Info,Indic e,Inicio,Disp,Elem ento); getch(); } void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp) { int Apuntador=Inicio; while(Apuntador!=- 999) { cout<<Info[Apuntad or]<<endl; Apuntador=Indice[A puntador]; } } void EliBusq(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento) { int Temp=Inicio,Temp2; if(Temp==-999) { cout<<"Lista Vacia... Imposible Eliminar"; return; } while(Temp!=-999) { if(Elemento==Info[
  • 40. 38 #include <stdio.h> #include <conio.h> #include <iomanip.h> #include <iostream.h> class Alumno { private: char Nombre[10][30]; int N_control[10],Edad[10] ,Indice1[10],Indice2[1 0],Inicio,Fin,Disp; public: //Constructor Alumno() { int i,j; Inicio=0; Fin=0; Disp=1; Indice1[Inicio]=-999; Indice2[Fin]=-999; for(i=1;j=2;i<9;i++; j++) Indice1[i]=j; Indice1[9]=-999; } //Funcion de Recorrido void Recorrido(int op) { int i=0,Temp; if(op==1) { Temp=Indice1[Inicio]; if(Temp!=-999) { cout<<"Numero de Control"<<setw(19)<<"N ombre del Alumno"<<setw(5)<<"Eda d"<<endl; while(Temp!=-999) { if(i==(int(Edad[Inicio ]/2))) { N_control[Inicio]=N control[i]; strcpy(Nombre[Inicio], Nombre[i]); } cout<<setw(9)<<N_contr ol[Temp]<<setw(22)<< Nombre[Temp]<<setw(9) <<Edad[Temp]<<endl; Temp=Indice1[Temp]; i++; } } else cout<<"Lista Vacia..."; } if(op==2) { Temp=Fin; if(Edad[Inicio]!=0) { cout<<"Numero de Control"<<setw(19)<<"N ombre del Alumno"<<setw(5)<<"Eda d"<<endl; while(Temp!=- 999&&i<Edad[Inicio]) { if(i==(int(Edad[Inicio ]/2))) { N_control[Inicio]=N_co ntrol[i]; strcpy(Nombre[Inicio], Nombre[i]); } cout<<setw(9)<<N_contr ol[Temp]<<setw(22)<<No mbre[Temp]<<setw(9)<<E dad[Temp]<<endl; Temp=Indice2[Temp]; i++; } } else cout<<"Lista Vacia..."; } } //Funcion de Busqueda Sobrecargada para un Dato Entero int Busqueda(int Elem) { if(Elem<N_control[ Inicio]) { int Temp=Indice1[Inicio]; while(Temp!=-999) { if(Elem==N_control[ Temp]) { gotoxy(1,10); cout<<"Numero de Control"<<setw(19)<<"N ombre del Alumno"<<setw(5)<<"Eda d"<<endl; cout<<setw(9)<<N_contr ol[Temp]<<setw(22)<<No mbre[Temp]<<setw(9)<<E dad[Temp]<<endl; return Temp; } else Temp=Indice1[Temp]; } } else { int Temp=Fin; while(Temp!=-999) { if(Elem==N_control[ Temp]) { gotoxy(1,10); cout<<"Numero de Control"<<setw(19)<< "Nombre del Alumno"<<setw(5)<<"Eda d"<<endl; cout<<setw(9)<<N_contr ol[Temp]<<setw(22)<< Nombre[Temp]<<setw(9) <<Edad[Temp]<<endl;
  • 41. 39 return Temp; } else Temp=Indice2[Temp]; } } return -999; } //Funcion de Busqueda Sobrecargada para una Cadena de Caracteres int Busqueda(char Elem[30]) { if((strcmp(Elem,Nombre [Inicio]))<0) { int Temp=Indice1[Inicio]; while(Temp!=-999) { if((strcmp(Elem,Nombre [Temp]))==0) { gotoxy(1,10); cout<<"Numero de Control"<<setw(19)<< "Nombre del Alumno"<<setw(5) <<"Edad"<<endl; cout<<setw(9) <<N_control[Temp] <<setw(22)<<Nombre[ Temp]<<setw(9)<<Edad[ Temp]<<endl; return Temp; } else Temp=Indice1[Temp]; } } else { int Temp=Fin; while(Temp!=-999) { if((strcmp(Elem,Nombre [Temp]))==0) { gotoxy(1,10); cout<<"Numero de Control"<<setw(19)<< "Nombre del Alumno"<<setw(5) <<"Edad"<<endl; cout<<setw(9) <<N_control[Temp] <<setw(22)<<Nombre[ Temp]<<setw(9)<<Edad[ Temp]<<endl; return Temp; } else Temp=Indice2[Temp]; } } return -999; } //Funcion Sobrecargada de Orden para un Dato Entero int Enca(int E_nc) { int Temp=Indice1[Inicio], Temp2; if(Temp==- 999||E_nc<N_control[ Temp]) return -999; Temp2=Indice1[Indice1[ Inicio]]; while(Temp2!=-999) { if(E_nc<N_control[ Temp2]) return Temp; Temp=Temp2; Temp2=Indice1[Temp2]; } return Temp; } //Funcion Sobrecargada de Orden para una Cadena de Caracteres int Enca(char E_nom[30]) { int Temp=Indice1[Inicio],T emp2; if(Temp==-999) return -999; if((strcmp(E_nom,Nombr [Temp]))<0) return Temp; Temp2=Indice1[Indice1[ Inicio]]; while(Temp2!=-999) { if((strcmp( E_nom,Nombre[Temp2])) <0) return Temp; Temp=Temp2; Temp2=Indice1[Temp2]; } return Temp; } //Funcion para la Insercion en un Lugar Determinado void InsLug(char E_nom[30],int E_nc,int E_edad,int Npos) { if(Disp!=-999) { Edad[Inicio]++; int Temp=Disp; Disp=Indice1[Disp]; strcpy(Nombre[Temp], E_nom); N_control[Temp]=E_nc; Edad[Temp]=E_edad; if(Npos==-999) { Indice1[Temp]=Indice1[ Inicio]; if(Indice2[Fin]==-999) { Indice2[Temp]=Fin; Fin=Temp; } else
  • 42. 40 { Indice2[Temp]=Indice1[ Inicio]; Indice2[Indice1[Inicio ]]=Temp; } Indice1[Inicio]=Temp; } else { Indice1[Temp]=Indice1[ Npos]; if(Fin==Npos) { Indice2[Temp]=Fin; Fin=Temp; } else { Indice2[Temp]=Npos; Indice2[Indice1[Npos]] =Temp; } Indice1[Npos]=Temp; } } else cout<<"Overflow..."<< endl; } //Funcion Sobrecargada para Borrar un Dato Entero void Borrar(int Elem) { int Temp2,Temp=Indice1[ Inicio]; if(Temp==-999) { cout<<"Lista Vacia... Imposible Eliminar"; return; } while(Temp!=-999) { if(Elem==N_control[ Temp]) { Edad[Inicio]--; if(Temp==Indice1[ Inicio]) { Indice1[Inicio]=Indice 1[Indice1[Inicio]]; Indice2[Indice1[ Inicio]]=Inicio; } else if(Temp==Fin) { Indice1[Temp2]=Indice1 [Temp]; Fin=Indice2[Fin]; } else { Indice1[Temp2]=Indice1 [Temp]; Indice2[Indice1[ Temp2]]=Temp2; } Indice1[Temp]=Disp; Disp=Temp; return; } else { Temp2=Temp; Temp=Indice1[Temp]; } } cout<<"Dato no encontrado... Imposible Eliminar"; return; } //Funcion Sobrecargada para Borrar una Cadena de Caracteres void Borrar(char Elem[30]) { int Temp2,Temp=Indice1[ Inicio]; if(Temp==Inicio) { cout<<"Lista Vacia... Imposible Eliminar"; return; } while(Temp!=Inicio) { if((strcmp(Elem,Nombre [Temp]))==0) { Edad[Inicio]--; if(Temp==Indice1[Inici o]) { Indice1[Inicio]=Indice 1[Indice1[Inicio]]; Indice2[Indice1[ Inicio]]=Inicio; } else if(Temp==Fin) { Indice1[Temp2]=Indice1 [Temp]; Fin=Indice2[Fin]; } else { Indice1[Temp2]=Indice1 [Temp]; Indice2[Indice1[ Temp2]]=Temp2; } Indice1[Temp]=Disp; Disp=Temp; return; } else { Temp2=Temp; Temp=Indice1[Temp]; } } cout<<"Dato no encontrado... Imposible Eliminar"; return; } }tec; main() { int op=0,res; char inom[30]; int in_c,iedad;
  • 43. 41 while(op!=6) { clrscr(); cout<<"n1) Recorrido por Inicion2) Recorrido por Finaln3) Busquedan"; cout<<"4) Insercionn5) Eliminar un Daton6) Salir"<<endl; gotoxy(1,1); cout<<"Que deseas hacer: "; cin>>op; gotoxy(1,10); switch (op) { case 1: tec.Recorrido(1); break; case 2: tec.Recorrido(2); break; case 3: cout<<"Que Numero de Control deseas buscar?"<<endl; cin>>res; res=tec.Busqueda(res); if(res==-999) cout<<"Dato no encontrado"; break; case 4: cout<<"Que nombre quieres Insertar?"<<endl; gets(inom); cout<<"Cual es su Numero de Control?"<<endl; cin>>in_c; cout<<"Cual es su Edad?"<<endl; cin>>iedad; res=tec.Enca(in_c); tec.InsLug(inom,in_c, iedad,res); break; case 5: cout<<"Que Numero de Control deseas eliminar?"<<endl; cin>>res; tec.Borrar(res); break; case 6: cout<<"Salida..."; break; default: cout<<"Opcion Erronea"<<endl; break; } getch(); } }
  • 44. 42 3.4 Listas Circulares: Recorrido simplemente despliega los datos almacenados en el arreglo Info, con ayuda de un segundo arreglo llamado Índice el cual guarda el orden en el que encuentran enlazados cada uno de los datos. Detalle: Apuntador toma el valor de Indice[Inicio], después ve si la condición cumple para efectuar un Ciclo mientras Apuntador sea diferente de Inicio, si cumple lo que hace es que despliega la Info[Apuntador], después Apuntador toma el valor de Indice[Apuntador] (El cual nos indica el siguiente nodo que sigue en la lista) y hace esto hasta que Apuntador sea igual a Inicio (Cuando llega a este punto a llegado al fin de la Lista). Algoritmo: Recorrido(Inicio, Info, Indice) Apuntador → Indice[Inicio] Repetir mientras Apuntador ≠ Inicio Imprimir Info[Apuntador] Apuntador → Indice[Apuntador] Fin del ciclo Salir Diagrama:
  • 45. 43 Programa: #include <conio.h> #include <iostream.h> void Recorrido(char Info[8][2],int Indice[8],int Inicio,int Disp); void main() { char Info[8][2]={{" "},{"I"},{" "},{"T"},{"O"},{"A"}, {"G"},{"T"}}; int Indice[8]={6,7,-999,1,0,3,5,4}; int Inicio=0,Disp=2; cout<<"El Recorrido es:n"; Recorrido(Info,Indice,Inicio,Disp); getch(); } void Recorrido(char Info[8][2],int Indice[8],int Inicio,int Disp) { int Apuntador=Indice[Inicio]; while(Apuntador!=Inicio) { cout<<Info[Apuntador]; Apuntador=Indice[Apuntador]; } } Corrida: Búsqueda La Búsqueda su objetivo es encontrar un dato en el arreglo Info, si lo encuentra lo desplegara en la pantalla, si no lo encuentra no desplegara nada ya que el dato no se encuentra en el arreglo Info.
  • 46. 44 Detalle: Apuntador toma el valor de Inicio, después ve si la condición cumple para efectuar un Ciclo mientras Apuntador sea diferente de 0, si cumple lo que hace a continuación es la comparación de Elemento (El dato que vamos a buscar) con Info[Apuntador], cuando lo encuentre lo despliega y sale del método. Si no, regresa el valor de Apuntador para así saber que no se encontró el dato. Algoritmo: Recorrido(Inicio, Info, Indice, Elemento) Apuntador → Indice[Inicio] Repetir mientras Apuntador ≠ Inicio Si Elemento = Info[Apuntador] entonces: Imprimir Info[Apuntador] Regresa Apuntador Apuntador → Indice[Apuntador] Fin del ciclo Regresar Apuntador Diagrama:
  • 47. 45 Programa: #include <conio.h> #include <iostream.h> int Busqueda(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento); void main() { int Info[8]={0,10,0,9,5,3,0,20}; int Indice[8]={5,7,6,1,0,3,-999,4}; int Inicio=0,Disp=2,Elemento,Res; cout<<"Que Numero deseas buscar?"; cin>>Elemento; Res=Busqueda(Info,Indice,Inicio,Disp,Elemento); if(Res==-999) cout<<"Dato No Encontrado..."; getch(); } int Busqueda(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento) { int Apuntador=Indice[Inicio]; while(Apuntador!=Inicio) { if(Elemento==Info[Apuntador]) { cout<<"Numero "<<Info[Apuntador]<<" encontrado..."; return Apuntador; } Apuntador=Indice[Apuntador]; } return Apuntador; }
  • 48. 46 Corrida: Inserción al Principio La Inserción al Principio básicamente busca si existe algún lugar disponible en el arreglo Info y lo agrega como primer Nodo si es que es posible. Detalle: Hace una comparación para ver si es posible insertar otro Elemento al arreglo Info, para esto checa si Disp es Diferente de Nulo. Si no cumple con la condición se desplegar “Sobre Carga” ya que no se puede insertar un Nuevo Elemento. Si es cierto Apuntador toma el valor de Inicio, Disp cambia a Indice[Disp] ya que el primer Disp tomara el valor del Nuevo Elemento, después de esto solo copia la información de Elemento al arreglo Info en la posición que guarda Apuntador, Indice[Apuntador] toma el valor de Indice[Inicio] y finalmente Indice[Inicio] toma el valor de Apuntador. Algoritmo: InsPr(Inicio, Disp, Info, Indice, Elemento) Si Disp ≠ Nill entonces: Apuntador → Disp Disp → Indice[Disp] Info[Apuntador] → Elemento Indice[Apuntador] → Indice[Inicio] Indice[Inicio] → Apuntador Si no: Imprimir “Sobre Carga” Salir
  • 49. 47 Diagrama: Programa: #include <conio.h> #include <iostream.h> void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp); void InsPr(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento); void main() { int Info[8]={0,10,0,9, 5,3,0,20}; int Indice[8]={5,7,6,1 ,0,3,-999,4}; int Inicio=0,Disp=2,El emento,Res; cout<<"Lista Originaln"; Recorrido(Info,Ind ice,Inicio,Disp); cout<<"Que Numero deseas Insertar?"; cin>>Elemento; InsPr(Info,Indice, Inicio,Disp,Elemen to); getch(); } void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp) { int Apuntador=Indice[I nicio]; while(Apuntador!=I nicio) { cout<<Info[Apuntad or]<<endl; Apuntador=Indice[A puntador]; } } void InsPr(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento) { if(Disp!=-999) { int Apuntador=Disp; Disp=Indice[Disp]; Info[Apuntador]=El emento; Indice[Apuntador]= Indice[Inicio]; Indice[Inicio]=Apu ntador; Recorrido(Info,Ind ice,Inicio,Disp); } else cout<<"Overflow... "; }
  • 50. 48 Corrida: Inserción después de un Nodo Determinado La Inserción después de un Nodo Determinado básicamente hace lo mismo que la inserción al principio, la única diferencia es que este recibe la posición del nodo en la que será Insertada. Este Algoritmo se usa para Inserción Ordenada que más adelante explicaremos. Detalle: Primero confirma que sea posible insertar el Dato, si no es posible solo desplegara “Sobre Carga”. Si es posible insertar un dato nuevo lo posiciona en la primer posición Disponible en el arreglo Info, después compara la Nueva Posición (Npos) que le mandamos con Nill si cumple la condición el dato es insertado en la primer posición, de otra forma se posicionara en la posición que guarde Npos. Algoritmo: InsOrd(Inicio, Disp, Info, Indice, Elemento, Npos) Si Disp ≠ Nill entonces: Apuntador → Disp Disp → Indice[Disp] Info [Apuntador] → Elemento Si Npos = Nill entonces: Indice[Apuntador] → Indice[Inicio] Indice[Inicio] → Apuntador Si no: Indice[Apuntador] → Indice[Npos] Indice[Npos] → Apuntador Si no: Imprimir “Sobre Carga” Salir Inserción Ordenada La Inserción Ordenada busca la posición en donde será Insertado el Elemento y la posición anterior donde será Insertado, después de encontrar la posición en la que será Insertado
  • 51. 49 el Elemento nos regresa ese valor y lo mandamos al método de la Inserción después de un Nodo. Detalle: En esta ocasión usaremos dos variables para determinar la posición deseada, comparamos si Indice[Inicio] es igual a Inicio ó si Elemento es menor al dato que se encuentra en Info[Inicio], si alguna de las dos cumple regresamos Nill, de esta manera Indicamos que el Elemento será el primero de todo el Arreglo Info, si no es así Temp tomara el valor de Inicio y Temp2 de la posición que le sigue a Inicio. Hace un ciclo hasta encontrar la posición en donde se insertara el Nuevo Elemento y va moviéndose de posición con las variables Temp y Temp2 para así determinar que posición debe de regresar. Algoritmo: InsOrd(Inicio, Info, Indice, Elemento) Si Inicio = Indice[Inicio] ó Elemento < Info[Inicio] entonces: Regresar Nill Temp → Indice[Inicio] Temp2 → Indice[Temp] Repetir mientras Temp2 ≠ Inicio Si Elemento < Info[Temp2] Regresar Temp Temp → Temp2 Temp2 → Indice[Temp2] Regresar Temp Diagrama:
  • 52. 50 Programa: #include <stdio.h> #include <conio.h> #include <iostream.h> void Recorrido(char Info[8][10],int Indice[8],int Inicio,int Disp); void InsPr(char Info[8][10],int Indice[8],int Inicio,int Disp,char Elemento[10]); void InsOrd(char Info[8][10],int Indice[8],int Inicio,int Disp,char Elemento[10]); void main() { char Info[8][10]={{"Cab eza"},{"e"},{" "},{"c"},{"i"},{"a "},{" "},{"g"}}; char Elemento[10]; int Indice[8]={5,7,6,1 ,0,3,-999,4}; int Inicio=0,Disp=2,Re s; cout<<"Lista Originaln"; Recorrido(Info,Ind ice,Inicio,Disp); cout<<"Que Numero deseas Insertar?"; gets(Elemento); InsOrd(Info,Indice ,Inicio,Disp,Eleme nto); getch(); } void Recorrido(char Info[8][10],int Indice[8],int Inicio,int Disp) { int Apuntador=Indice[I nicio]; while(Apuntador!=I nicio) { cout<<Info[Apuntad or]<<endl; Apuntador=Indice[A puntador]; } } void InsPr(char Info[8][10],int Indice[8],int Inicio,int Disp,char Elemento[10]) { if(Disp!=-999) { strcpy(Info[Disp], Elemento); Indice[Disp]=Indic e[Inicio]; Indice[Inicio]=Dis p; Disp=Indice[Disp]; } Recorrido(Info,Ind ice,Inicio,Disp); } void InsOrd(char Info[8][10],int Indice[8],int Inicio,int Disp,char Elemento[10]) { if(Inicio==Indice[ Inicio]||(strcmp(E lemento,Info[Indic e[Inicio]]))==0) { InsPr(Info,Indice, Inicio,Disp,Elemen to); return; } int Temp=Indice[Inicio ],Temp2=Indice[Tem p]; while(Temp2!=Inici o) { if((strcmp(Element o,Info[Temp2]))<0) break; Temp=Temp2; Temp2=Indice[Temp2 ]; } strcpy(Info[Disp], Elemento); Indice[Disp]=Indic e[Temp]; Indice[Temp]=Disp; Disp=Indice[Disp]; Recorrido(Info,Ind ice,Inicio,Disp); }
  • 53. 51 Eliminación por Búsqueda La Eliminación simplemente cambia los nodos para que el dato que se desea eliminar sea el primer disponible, de esta forma ya no estará en el Arreglo de Info. Detalle: Lo primero que hace es ver si existe algún dato en la lista para eliminar, si Indice[Inicio] es igual a Inicio entonces solo desplegara “Imposible Eliminar”. De otra formas cambiar de Posición en Posición hasta encontrar el Elemento que sea desea Eliminar con ayudar de dos variables que guardan la Posición actual y la anterior en donde se encuentre el dato. Ya que lo encuentra cambia ese dato como la primera posición Disponible y lo apunta al siguiente nodo disponible. Si no encuentra el dato simplemente desplegara “Dato no encontrado” Algoritmo: EliBusq(Inicio, Info, Indice, Elemento) Temp → Indice[Inicio] Si Temp = Inicio Imprimir “Lista Vacia… Imposible Eliminar” y Retornar Repetir mientras Temp ≠ Inicio Si Elemento = Info[Temp] entonces: Si Temp = Indice[Inicio] entonces: Indice[Inicio] → Indice[Indice[Inicio]] Si no: Indice[Temp2] → Indice[Temp] Indice[Temp] → Disp Disp → Temp Recorrido(Inicio, Info, Indice) y Retornar Si no: Temp2 → Temp Temp → Indice[Temp] Imprimir “Dato no encontrado… Imposible Eliminar” y Retornar Diagrama:
  • 54. 52 Programa: #include <conio.h> #include <iostream.h> void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp); void EliBusq(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento); void main() { int Info[8]={0,10,0,9, 5,3,0,20}; int Indice[8]={5,7,6,1 ,0,3,-999,4}; int Inicio=0,Disp=2,El emento,Res; cout<<"Lista Originaln"; Recorrido(Info,Ind ice,Inicio,Disp); cout<<"Que Numero deseas Eliminar?"; cin>>Elemento; EliBusq(Info,Indic e,Inicio,Disp,Elem ento); getch(); } void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp) { int Apuntador=Indice[I nicio]; while(Apuntador!=I nicio) { cout<<Info[Apuntad or]<<endl; Apuntador=Indice[A puntador]; } } void EliBusq(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento) { int Temp=Indice[Inicio ],Temp2; if(Temp==Inicio) { cout<<"Lista Vacia... Imposible Eliminar"; return; } while(Temp!=Inicio ) { if(Elemento==Info[ Temp]) { if(Temp==Inicio) Inicio=Indice[Inic io]; else Indice[Temp2]=Indi ce[Temp]; Indice[Temp]=Disp; Disp=Temp; Recorrido(Info,Ind ice,Inicio,Disp); return; } else { Temp2=Temp; Temp=Indice[Temp]; } } cout<<"Dato no encontrado... Imposible Eliminar"; return; }
  • 55. 53 Corrida: 3.5 Listas Dobles: El Recorrido simplemente despliega los datos almacenados en el arreglo Info, con ayuda de un segundo arreglo llamado Indice1 o Indice2 el cual guarda el orden en el que encuentran enlazados cada uno de los datos. Estos datos se pueden recorrer de Arriba hacia Abajo o de Abajo hacia Arriba. Explicación: Dependiendo de la forma en la que se desea recorrer el Arreglo, la variable Apuntador tomara el valor de Indice1[Inicio], o de Fin. Después recorrerá el Arreglo mientras la condición no se rompa (Dicha condición será diferente dependiendo el caso). Diagrama: Búsqueda La Búsqueda su objetivo es encontrar un dato en el arreglo Info, si lo encuentra lo desplegara en la pantalla, si no lo encuentra no desplegara nada ya que el dato no se
  • 56. 54 encuentra en el arreglo Info. Esta búsqueda es más efectiva ya que compara el dato de la mitad y dependiendo el resultado, empezara la búsqueda por el Final o Inicio. Explicación: Primeramente usaremos un contador y la cabecera, esto nos permitirá determinar cuál es dato de la mitad. Para esto se utiliza el Recorrido el cual al encontrar el Dato de la mitad lo copia ese dato a la cabecera con la cual se comparara para determinar por dónde empezar (Inicio y Fin). Diagrama: Inserción Ordenada Definición: La Inserción Ordenada busca la posición en donde será Insertado el Elemento y la posición anterior donde será Insertado, después de encontrar la posición en la que será Insertado el Elemento nos regresa ese valor y lo mandamos al método de la Inserción después de un Nodo. Explicación: Esta Inserción ordenada es similar a las anteriores aunque en este caso consta de mas comparación y movimientos de variables, esto se debe a que tenemos 2 arreglos que nos indican los movimientos y al insertar un dato ambos arreglos deben direccionar nuevamente.
  • 57. 55 Diagrama: Eliminación por Búsqueda La Eliminación simplemente cambia los nodos para que el dato que se desea eliminar sea el primer disponible, de esta forma ya no estará en el Arreglo de Info. Explicación: Lo primero que hace es ver si existe algún dato en la lista para eliminar, si Indice[Inicio] es igual a Inicio entonces solo desplegara “Imposible Eliminar”. De otra formas cambiar de Posición en Posición hasta encontrar el Elemento que sea desea Eliminar con ayudar de dos variables que guardan la Posición actual y la anterior en donde se encuentre el dato. Ya que lo encuentra cambia ese dato como la primera posición Disponible y lo apunta al siguiente nodo disponible. Si no encuentra el dato simplemente desplegara “Dato no encontrado”
  • 59. 57 #include <stdio.h> #include <conio.h> #include <iomanip.h> #include <iostream.h> class Alumno { private: char Nombre[10][30]; int N_control[10],Edad[10] ,Indice1[10],Indice2[ 10],Inicio,Fin,Disp; public: //Constructor Alumno() { int i,j; Inicio=0; Fin=0; Disp=1; Indice1[Inicio]=-999; Indice2[Fin]=-999; for(i=1,j=2;i<9;i++, j++) Indice1[i]=j; Indice1[9]=-999; } //Funcion de Recorrido void Recorrido(int op) { int i=0,Temp; if(op==1) { Temp=Indice1[Inicio]; if(Temp!=-999) { cout<<"Numero de Control"<<setw(19) <<"Nombre del Alumno"<<setw(5) <<"Edad"<<endl; while(Temp!=-999) { if(i==(int(Edad[Inicio ]/2))) { N_control[Inicio]= N_control[i]; strcpy(Nombre[Inicio], Nombre[i]); } cout<<setw(9) <<N_control[Temp] <<setw(22) <<Nombre[Temp] <<setw(9) <<Edad[Temp]<<endl; Temp=Indice1[Temp]; i++; } } else cout<<"Lista Vacia.."; } if(op==2) { Temp=Fin; if(Edad[Inicio]!=0) { cout<<"Numero de Control"<<setw(19) <<"Nombre del Alumno"<<setw(5) <<"Edad"<<endl; while(Temp!=- 999&&i<Edad[Inicio]) { if(i==(int(Edad[Inicio ]/2))) { N_control[Inicio]= N_control[i]; strcpy(Nombre[Inicio], Nombre[i]); } cout<<setw(9) <<N_control[Temp] <<setw(22)<<Nombre[ Temp]<<setw(9) <<Edad[Temp]<<endl; Temp=Indice2[Temp]; i++; } } else cout<<"Lista Vacia.."; } } //Funcion Sobrecargada de Busqueda para Enteros int Busqueda(int Elem) { if(Elem<N_control[ Inicio]) { int Temp=Indice1[Inicio]; while(Temp!=-999) { if(Elem==N_control[ Temp]) { gotoxy(1,10); cout<<"Numero de Control"<<setw(19) <<"Nombre del Alumno"<<setw(5) <<"Edad"<<endl; cout<<setw(9) <<N_control[Temp] <<setw(22)<<Nombre[ Temp]<<setw(9) <<Edad[Temp]<<endl; return Temp; } else Temp=Indice1[Temp]; } } else { int Temp=Fin; while(Temp!=-999) { if(Elem==N_control[ Temp]) { gotoxy(1,10); cout<<"Numero de Control"<<setw(19) <<"Nombre del Alumno"<<setw(5) <<"Edad"<<endl; cout<<setw(9) <<N_control[Temp] <<setw(22)<<Nombre[
  • 60. 58 Temp]<<setw(9)<<Edad[ Temp]<<endl; return Temp; } else Temp=Indice2[Temp]; } } return -999; } //Funcion Sobrecargada de Busqueda de Cadenas de Caracteres int Busqueda(char Elem[30]) { if((strcmp(Elem,Nombre [Inicio]))<0) { int Temp=Indice1[Inicio]; while(Temp!=-999) { if((strcmp(Elem,Nombre [Temp]))==0) { gotoxy(1,10); cout<<"Numero de Control"<<setw(19) <<"Nombre del Alumno"<<setw(5) <<"Edad"<<endl; cout<<setw(9 )<<N_control[Temp] <<setw(22)<<Nombre[ Temp]<<setw(9)<<Edad[ Temp]<<endl; return Temp; } else Temp=Indice1[Temp]; } } else { int Temp=Fin; while(Temp!=-999) { if((strcmp(Elem,Nombre [Temp]))==0) { gotoxy(1,10); cout<<"Numero de Control"<<setw(19) <<"Nombre del Alumno"<<setw(5) <<"Edad"<<endl; cout<<setw(9) <<N_control[Temp] <<setw(22)<<Nombre[ Temp]<<setw(9)<<Edad[ Temp]<<endl; return Temp; } else Temp=Indice2[Temp]; } } return -999; } //Funcion Sobrecargada de Orden para Numeros Enteros int Enca(int E_nc) { int Temp=Indice1[Inicio],T emp2; if(Temp==- 999||E_nc<N_control[ Temp]) return -999; Temp2=Indice1[Indice1[ Inicio]]; while(Temp2!=-999) { if(E_nc<N_control[ Temp2]) return Temp; Temp=Temp2; Temp2=Indice1[Temp2]; } return Temp; } //Funcion Sobrecargada de Orden para Cadena de Caracteres int Enca(char E_nom[30]) { int Temp=Indice1[Inicio], Temp2; if(Temp==-999) return -999; if((strcmp(E_nom, Nombre[Temp]))<0) return Temp; Temp2=Indice1[Indice1[ Inicio]]; while(Temp2!=-999) { if((strcmp(E_nom, Nombre[Temp2]))<0) return Temp; Temp=Temp2; Temp2=Indice1[Temp2]; } return Temp; } //Funcion de Inserción en un Lugar Determinado void InsLug(char E_nom[30],int E_nc,int E_edad,int Npos) { if(Disp!=-999) { Edad[Inicio]++; int Temp=Disp; Disp=Indice1[Disp]; strcpy(Nombre[Temp], E_nom); N_control[Temp]=E_nc; Edad[Temp]=E_edad; if(Npos==-999) { Indice1[Temp]=Indice1[ Inicio]; if(Indice2[Fin]==-999) { Indice2[Temp]=Fin; Fin=Temp; } else
  • 61. 59 { Indice2[Temp]=Indice1[ Inicio]; Indice2[Indice1[ Inicio]]=Temp; } Indice1[Inicio]=Temp; } else { Indice1[Temp]=Indice1[ Npos]; if(Fin==Npos) { Indice2[Temp]=Fin; Fin=Temp; } else { Indice2[Temp]=Npos; Indice2[Indice1[Npos]] =Temp; } Indice1[Npos]=Temp; } } else cout<<"Overflow..." <<endl; } //Funcion Sobrecargada para Borrar un Dato que sea Entero void Borrar(int Elem) { int Temp2,Temp=Indice1[Ini cio]; if(Temp==-999) { cout<<"Lista Vacia... Imposible Eliminar"; return; } while(Temp!=-999) { if(Elem==N_control[ Temp]) { Edad[Inicio]--; if(Temp==Indice1[ Inicio]) { Indice1[Inicio]=Indice 1[Indice1[Inicio]]; Indice2[Indice1[ Inicio]]=Inicio; } else if(Temp==Fin) { Indice1[Temp2]=Indice1 [Temp]; Fin=Indice2[Fin]; } else { Indice1[Temp2]=Indice1 [Temp]; Indice2[Indice1[ Temp2]]=Temp2; } Indice1[Temp]=Disp; Disp=Temp; return; } else { Temp2=Temp; Temp=Indice1[Temp]; } } cout<<"Dato no encontrado... Imposible Eliminar"; return; } //Funcion Sobrecargada para Borrar una Cadena de Caracteres void Borrar(char Elem[30]) { int Temp2,Temp=Indice1[ Inicio]; if(Temp==Inicio) { cout<<"Lista Vacia... Imposible Eliminar"; return; } while(Temp!=Inicio) { if((strcmp(Elem,Nombre [Temp]))==0) { Edad[Inicio]--; if(Temp==Indice1[ Inicio]) { Indice1[Inicio]=Indice 1[Indice1[Inicio]]; Indice2[Indice1[ Inicio]]=Inicio; } else if(Temp==Fin) { Indice1[Temp2]=Indice1 [Temp]; Fin=Indice2[Fin]; } else { Indice1[Temp2]=Indice1 [Temp]; Indice2[Indice1[ Temp2]]=Temp2; } Indice1[Temp]=Disp; Disp=Temp; return; } else { Temp2=Temp; Temp=Indice1[Temp]; } } cout<<"Dato no encontrado... Imposible Eliminar"; return; } }tec; main() { int op=0,res; char inom[30]; int in_c,iedad;
  • 62. 60 while(op!=6) { clrscr(); cout<<"n1) Recorrido por Inicion2) Recorrido por Finaln3) Busquedan"; cout<<"4) Insercionn5) Eliminar un Daton6) Salir"<<endl; gotoxy(1,1); cout<<"Que deseas hacer: "; cin>>op; gotoxy(1,10); switch (op) { case 1: tec.Recorrido(1); break; case 2: tec.Recorrido(2); break; case 3: cout<<"Que Numero de Control deseas buscar?"<<endl; cin>>res; res=tec.Busqueda(res); if(res==-999) cout<<"Dato no encontrado"; break; case 4: cout<<"Que nombre quieres Insertar?"<<endl; gets(inom); cout<<"Cual es su Numero de Control?"<<endl; cin>>in_c; cout<<"Cual es su Edad?"<<endl; cin>>iedad; res=tec.Enca(in_c); tec.InsLug(inom,in_c,i edad,res); break; case 5: cout<<"Que Numero de Control deseas eliminar?"<<endl; cin>>res; tec.Borrar(res); break; case 6: cout<<"Salida..."; break; default: cout<<"Opcion Erronea"<<endl; break; } getch(); } }
  • 63. 61 Unidad 4: Recursividad Capacidad que tiene los métodos de invocarse a sí mismos, esta es una potente herramienta en la informática. Con esta herramienta muchos algoritmos pueden simplificarse significativamente. Programa: #include <stdio.h> #include <conio.h> #include <string.h> #include <iomanip.h> #include <iostream.h> class Matematicas { public: void Tablas(int T,int B) { if(B<11) { cout<<T<<" X "<<setw(2)<<B<<" = "<<(T*B)<<endl; Tablas(T,B+1); } return; } long Factorial(long n) { if(n<=1) return 1; else return (n* Factorial(n - 1)); } void Formula(int X) { if(X<11) { cout<<"f("<<X<<") = "<<((X*X*X)+(2*X)+ (3))<<endl; Formula(X+1); } return; } void Torres(int N,char Inicio,char Aux,char Fin) { if(N==1) { cout<<Inicio<<" -- > "<<Fin<<endl; return; } Torres(N- 1,Inicio,Fin,Aux); cout<<Inicio<<" -- > "<<Fin<<endl; Torres(N- 1,Aux,Inicio,Fin); return; } }tec; main() { int t,b,op=0; while(op!=5) { clrscr(); cout<<"n1) Tablas de Multiplicarn2) Factorial de un Numeron"; cout<<"3) Formula Linealn4) Torres de Hanoin5) Salida"<<endl; gotoxy(1,1); cout<<"Que deseas hacer: "; cin>>op; clrscr(); switch(op) { case 1: cout<<"Que Tabla de Multiplicar deseas Imprimir?"<<endl; cin>>t; cout<<"Desde que Numero deseas empezar a multiplicar (Menor que 10)"<<endl; cin>>b; tec.Tablas(t,b); break; case 2: cout<<"Que Factorial deseas conocer"<<endl; cin>>t;
  • 64. 62 cout<<t<<"! = "<<tec.Factorial(t )<<endl; break; case 3: cout<<"f(x) = x^3 + 2x + 3"<<endl; cout<<"Escribe la Base (Menor de 10)"<<endl; cin>>t; tec.Formula(t); break; case 4: cout<<"Cuantos discos deseas mover?"<<endl; cin>>t; tec.Torres(t,'A',' B','C'); break; case 5: cout<<"Salida..."; break; default: cout<<"Opcion Erronea..."; break; } getch(); } }
  • 65. 63 Unidad 5: Arboles 5.1 Arboles Binarios: Un Árbol Binario es un conjunto de finito de Elementos, de nombre Nodos de forma que: El Árbol Binario es Vació si no tiene ningún elemento en él. El Árbol Binario contiene un Nodo Raíz y los dos que parten de él, llamados Nodo Izquierdo y Nodo Derecho. Los Árboles tienen 3 Recorridos Diferentes los cuales son: • Pre-Orden • In-Orden • Post-Orden • Pre-Orden El Recorrido “Pre-Orden” lo recorre de la siguiente manera, viaje a través del Árbol Binario desplegando el Contenido en la Raíz, después viaje a través del Nodo Izquierdo y después a través del Nodo Derecho. Detalle: Temp toma el Valor de la Raíz y compara si el Árbol tiene algún Elemento, de otra manera Desplegara “Árbol Vació…” y terminara el método. Si el Árbol tiene elementos dentro de él, lo recorrerá y viajara a través de los Arreglos Izq y Der para determinar qué valor meter en la Pila y en Temp para de esta manera imprimir el siguiente Elemento correspondiente. Algoritmo: PreOrd(Arbol, Der, Izq, Pila, Raiz) Temp → Raiz Top → Pila[Top] → Nulo Si Raiz = Nulo Imprimir “Árbol Vació…” y Salir Repetir mientras Temp ≠ Nulo Imprimir Arbol[Temp] Si Der[Temp] ≠ Nulo Top → Top + 1 Pila[Top] → Der[Temp] Si Izq[Temp] ≠ Nulo Temp → Izq[Temp] Si no: Temp → Pila[Top]; Top → Top - 1 Fin del ciclo Salir
  • 66. 64 Diagrama: Corrida: In-Orden El Recorrido “In-Orden” lo recorre de la siguiente manera, viaje a través del Árbol Binario desplegando el Contenido en el Nodo Izquierdo después la Raíz y finalmente viaja a través del Nodo Derecho. Detalle: Temp toma el Valor de la Raíz y compara si el Árbol tiene algún Elemento, de otra manera Desplegara “Árbol Vació…” y terminara el método. Si el Árbol tiene elementos dentro de él, lo recorrerá y viajara a través de los Arreglos Izq y Der para determinar qué valor meter en la Pila y en Temp para de esta manera imprimir el siguiente Elemento correspondiente.
  • 67. 65 Algoritmo: PreOrd(Arbol, Der, Izq, Pila, Raiz) Temp → Raiz Top → Pila[Top] → Nulo Si Raiz = Nulo Imprmir “Arbol Vacio…” y Salir Etiqueta: Mientras Temp ≠ Nulo Top → Top + 1 Pila[Top] → Temp Temp → Izq[Temp] Fin del ciclo Temp → Pila[Top] Top → Top - 1 Mientras Temp ≠ Nulo Imprimir Arbol[Temp] Si Der[Temp] ≠ Nulo Temp → Der[Temp] Ir a Etiqueta Temp → Pila[Top] Top → Top - 1 Fin del ciclo Salir Diagrama:
  • 68. 66 Corrida: In-Orden El Recorrido “In-Orden” lo recorre de la siguiente manera, viaje a través del Árbol Binario desplegando el Contenido en el Nodo Izquierdo después el Nodo Derecho y finalmente viaja a través de la Raiz. Detalle: Temp toma el Valor de la Raíz y compara si el Árbol tiene algún Elemento, de otra manera Desplegara “Árbol Vació…” y terminara el método. Si el Árbol tiene elementos dentro de él, lo recorrerá y viajara a través de los Arreglos Izq y Der para determinar que valor meter en la Pila y en Temp para de esta manera imprimir el siguiente Elemento correspondiente. Algoritmo: PostOrd(Arbol, Der, Izq, Pila, Raiz) Temp → Raiz Top → Pila[Top] → Nulo Si Raiz = Nulo Imprimir “Arbol Vacio…” y Salir Etiqueta: Mientras Temp ≠ Nulo Top → Top + 1 Pila[Top] → Temp Si Der[Temp] ≠ Nulo Top → Top + 1 Pila[Top] → - (Der[Temp]) Temp → Izq[Temp] Temp → Pila[Top] Top → Top - 1 Fin del ciclo Mientras Temp ≥ 0 Imprimir Arbol[Temp]
  • 69. 67 Si Arbol[Temp] = Info[Raiz] Salir Temp → Pila[Top] Top → Top - 1 Fin del ciclo Si Temp < 0 Temp = -(Temp) Ir a Etiqueta Salir Diagrama: Corrida:
  • 70. 68 Búsqueda La Búsqueda es Similar a todas los Métodos anteriores de Búsqueda, simplemente efectúa un recorrido comparando el Elemento que deseas encontrar contra cada uno de los Elementos en los Arreglos. Detalle: El Algoritmo de Búsqueda compara el Elemento a buscar con cada uno de los datos de nuestro Árbol, compara si el Elemento con el Nodo Raíz, si no se encuentra en la Raíz… compara Elemento contra la Raíz para empezar a viajar por el Árbol respectivamente, usa un método similar al anterior hasta encontrar el Elemento. De otra forma la búsqueda es fallida. Algoritmo: Busqueda(Arbol, Der, Izq, Pila, Raiz, Elem) Si Raiz = Nulo Imprimir “Arbol Vacio” Pos → Nulo Pad → Nulo Regresar Pos y Pad Salir Si Elem = Arbol[Raiz] Imprimir “Elemento Encontrado” Pos → Raiz Pad → Nulo Regresar Pos y Pad Salir Si Elem < Arbol[Raiz] Temp → Izq[Raiz] Temp2 → Raiz Si no: Temp → Der[Raiz] Temp2 → Raiz Mientras Temp ≠ Nulo Si Elem = Arbol[Temp] Imprimir “Elemento Encontrado…” Pos → Temp Pad → Temp2 Regresar Pos y Pad Salir Si Elem < Arbol[Temp] Temp2 → Temp Temp → Izq[Temp] Si no: Temp2 → Temp Temp → Der[Temp] Fin del ciclo Imprimir “Elemento no Encontrado…” Pos → Nulo Pad → Temp2 Regresar Pos y Pad Salir
  • 72. 70 #include <conio.h> #include <iostream.h> class Arbol { private: int Top,Pila[10]; int Info[10],Izq[10],Der[1 0],Raiz,Disp; public: Arbol() { int in[10]={0,0,0,0,0,0,0, 0,0,0}; for(int i=0;i<10;i++) { Info[i]=0; Izq[i]=i+1; Der[i]=-999; Pila[i]=0; } Top=0; Disp=0; Raiz=-999; Izq[9]=-999; } void PreOrd(void) { int Temp=Raiz; Top=0; Pila[0]=-999; if(Raiz==-999) { cout<<"Arbol Vacio..."<<endl; return; } while(Temp!=-999) { cout<<Info[Temp] <<endl; if(Der[Temp]!=-999) { Top++; Pila[Top]=Der[Temp]; } if(Izq[Temp]!=-999) { Temp=Izq[Temp]; } else { Temp=Pila[Top]; Top--; } } } void InOrd(void) { int Temp=Raiz, Top=0; Pila[0]=-999; if(Raiz==-999) { cout<<"Arbol Vacio..."<<endl; return; } Back: while(Temp!=-999) { Top++; Pila[Top]=Temp; Temp=Izq[Temp]; } Temp=Pila[Top]; Top--; while(Temp!=-999) { cout<<Info[Temp] <<endl; if(Der[Temp]!=-999) { Temp=Der[Temp]; goto Back; } Temp=Pila[Top]; Top--; } } void PostOrd(void) { int Temp=Raiz; Top=0; Pila[0]=-999; if(Raiz==-999) { cout<<"Arbol Vacio..."<<endl; return; } Back1: while(Temp!=-999) { Top++; Pila[Top]=Temp; if(Der[Temp]!=-999) { Top++; Pila[Top]=-Der[Temp]; } Temp=Izq[Temp]; } Temp=Pila[Top]; Top--; while(Temp>=0) { cout<<Info[Temp] <<endl; if(Info[Temp]==Info[ Raiz]) return; Temp=Pila[Top]; Top--; } if(Temp<0) { Temp=-Temp; goto Back1; } } void Busqueda(int PosPad[2],int Elem) { int Temp,Temp2; if(Raiz==-999) { PosPad[0]=-999; PosPad[1]=-999; cout<<"Arbol Vacio..."<<endl; return; } if(Elem==Info[Raiz]) { PosPad[0]=Raiz;
  • 73. 71 PosPad[1]=-999; cout<<"Elemento Encontrado..."<<endl; return; } if(Elem<Info[Raiz]) { Temp=Izq[Raiz]; Temp2=Raiz; } else { Temp=Der[Raiz]; Temp2=Raiz; } while(Temp!=-999) { if(Elem==Info[Temp]) { cout<<"Elemento Encontrado..."<<endl; PosPad[0]=Temp; PosPad[1]=Temp2; return; } if(Elem<Info[Temp]) { Temp2=Temp; Temp=Izq[Temp]; } else { Temp2=Temp; Temp=Der[Temp]; } } PosPad[0]=-999; PosPad[1]=Temp2; cout<<"Elemento no Encontrado..."<<endl; } void InsOrd(int Elem) { int PosPad[2],Temp; if(Disp!=-999) { Busqueda(PosPad,Elem); clrscr(); if(PosPad[0]!=-999) { cout<<"Elemento Existente... Imposible Insertar..."<<endl; return; } Temp=Disp; Disp=Izq[Disp]; Info[Temp]=Elem; PosPad[0]=Temp; Izq[Temp]=-999; Der[Temp]=-999; if(PosPad[1]==-999) Raiz=Temp; else if(Elem<Info[ PosPad[1]]) Izq[PosPad[1]]=Temp; else Der[PosPad[1]]=Temp; cout<<"Elemento Insertado..."<<endl; return; } cout<<"Arbol Lleno... Imposible Insertar..."<<endl; } void Eliminar(int Elem) { int PosPad[2]; Busqueda(PosPad,Elem); clrscr(); if(PosPad[0]==-999) { cout<<"El Elemento no se Encuentra en el Arbol... Imposible Eliminar..."<<endl; return; } if(Der[PosPad[0]]!=- 999&&Izq[PosPad[0]]!=- 999) CasoB(PosPad); else CasoA(PosPad); Izq[PosPad[0]]=Disp; Disp=PosPad[0]; } void CasoA(int PosPad[2]) { int Temp; if(Izq[PosPad[0]]==- 999&&Der[PosPad[0]]==- 999) Temp=-999; else if(Izq[PosPad[0]]!=- 999) Temp=Izq[PosPad[0]]; else Temp=Der[PosPad[0]]; if(PosPad[1]!=-999) { if(PosPad[0]==Izq[PosP ad[1]]) Izq[PosPad[1]]=Temp; else Der[PosPad[1]]=Temp; } else Raiz=Temp; } void CasoB(int PosPad[2]) { int PosPad2[2],Temp=Der[Po sPad[0]],Temp2=PosPad[ 0]; while(Izq[Temp]!=-999) { Temp2=Temp; Temp=Izq[Temp]; } PosPad2[0]=Temp; PosPad2[1]=Temp2; CasoA(PosPad2); if(PosPad[1]!=-999) { if(PosPad[0]==Izq[PosP ad[1]]) Izq[PosPad[1]]=PosPad2 [0];
  • 74. 72 else Der[PosPad[1]]=PosPad2 [0]; } else Raiz=PosPad2[0]; Izq[PosPad2[0]]=Izq[Po sPad[0]]; Der[PosPad2[0]]=Der[ PosPad[0]]; } }tec; main() { int PosPad[2],res,op=0; while(op!=7) { clrscr(); cout<<"n1) Pre-Ordenn2) In-Ordenn3) Post-Ordenn4) Busquedan5) Insercionn6) Eliminarn7) Salir"<<endl; gotoxy(1,1); cout<<"Que deseas hacer?: "; cin>>op; gotoxy(1,10); switch (op) { case 1: tec.PreOrd(); break; case 2: tec.InOrd(); break; case 3: tec.PostOrd(); break; case 4: cout<<"Que Numero deseas buscar?"<<endl; cin>>res; tec.Busqueda(PosPad, res); break; case 5: cout<<"Que Numero quieres Insertar?"<<endl; cin>>res; tec.InsOrd(res); break; case 6: cout<<"Que Numero quieres Eliminar?"<<endl; cin>>res; tec.Eliminar(res); break; case 7: cout<<"Salida..."; break; default: cout<<"Opcion Erronea"<<endl; break; } getch(); } }
  • 75. 73 5.2 Arboles en Monton El Árbol en Montón consiste en el ordenamiento de un conjunto de Elemento en un solo arreglo. Trabajaremos sobre la siguientes Operaciones en este Tema: 1. Inserción 2. Búsqueda 3. Eliminación 4. Recorrido (Ordenado) Inserción El Concepto de Inserción ya es familiar para nosotros y sabemos que para realizar el mismo no resulta complejo el procedimiento. Pero en los Árboles en Montón es uno de los Métodos más largos para efectuarlo. Detalle: Básicamente lo que hace estos Algoritmos es la Inserción Ordenada. Primero comparan si es posible insertar algún Elemento al Arreglo, si es posible hacerlo Ingresa el Elemento a la Última posición. Después básicamente acomoda el Arreglo con el Método de la Burbuja llamando a otra serie de Métodos. Algoritmos: Insertar(Arbol, N, Elemento) Si N<25 Arbol[N] -> a N -> N + 1 OrdMon(Arbol, N) Salir //Fin de la condición// Imprimir "Árbol Lleno..." Salir OrdMon(Arbol, Total) ConstMon(Arbol, Total) Mientras Total > 1 Total -> Total - 1 Burbuja(0, Total) RecMon(Total, 0) //Fin del ciclo// Salir ConstMon(Arbol, Total) v -> (Total/2) - 1 Mientras v ≥ 0 RecMon(Arbol, Total, v) v -> v - 1 //Fin del ciclo// Salir ---- RecMon(Arbol, Total, v) w -> 2*v+1 Mientras w < Total Si (w+1) < Total Si Arbol[w+1] > Arbol[w] w++ //Fin de la condición// Fin de la condición Si Arbol[v] ≥ Arbol[w] Salir //Fin de la condición// Burbuja(Arbol, v, w) v -> w w -> 2*v+1 //Fin del ciclo// Salir ---- Burbuja(Arbol, v, w) t -> Arbol[v] Arbol[v] -> Arbol[w] Arbol[w] -> t Salir
  • 76. 74 Diagrama: Corrida: Búsqueda El Concepto de Búsqueda es sencillo, simplemente es un método de búsqueda lineal. Existen 3 posible resultados: 1. Que el Árbol este Vació y no se puede realizar la búsqueda. 2. Que el Elemento sea encuentre en el Árbol 3. Que el Elemento no esté dentro del Árbol Detalle: Se manda al Método Búsqueda el Dato que se desea buscar, se acomoda el Árbol en Orden en caso que no estuviera Ordenado y después compara con cada uno de los datos.
  • 77. 75 Algoritmos: **Busqueda(Arbol, N, Elemento)** Si N ≠ 0 OrdMon(Arbol, N) i -> Mientras i < N;i++) Si Arbol[i] = Elemento Imprimir "Elemento Encontrado..." Salir //Fin de la condición// i -> i + 1 //Fin del ciclo// Imprimir "El Elemento no esta en el Árbol..." Salir //Fin de la condición// Imprimir "Árbol Vació..." Salir Diagrama:
  • 78. 76 Corrida: Eliminación El Concepto de Eliminación consiste en la búsqueda de un Elemento y sacarlo del Arreglo. Existen 3 casos Diferentes; 1. Que el Árbol este Vació y no se puede realizar la eliminación 2. Que el Elemento sea encuentre en el Árbol y sea eliminado 3. Que el Elemento no esté dentro del Árbol por lo tanto no se elimina Detalle: Vemos si el Árbol tiene Elementos insertados en él, de otra forma será imposible realizar la Eliminación ya que esta Vació. Después si el Árbol tiene Elementos lo ordenamos y hacemos un búsqueda lineal para encontrar el dato. Después usamos el método de la Burbuja para dejar el Elemento Eliminado hasta el final y le Restamos a N un Elemento. Algoritmo: Eliminar(Arbol, N, Elemento) Si N ≠ 0 OrdMon(Arbol, N) i -> Mientras I < N Si Arbol[i] = Elemento j -> i + 1 Mientras j < N t -> Arbol[i] Arbol[i] -> Arbol[j] Arbol[j] -> t j -> j + 1 //Fin del ciclo// N -> n - 1 Imprimir "Elemento Eliminado..." Salir //Fin de la condición// i -> i + 1 //Fin del ciclo// Fin de la condición Imprimir "Arbol Vacio... Imposible Eliminar..." Salir
  • 79. 77 Diagrama: Corrida: Recorrido (Ordenado) El Recorrido simplemente ira desplegando cada uno de los Elementos del Árbol. Solo existen 2 posibles casos: 1. Que el Árbol este Vació y no se pueda recorrer 2. El Árbol tenga Elementos para desplegar Detalle: Comparamos para comprobar que el Árbol tiene Elementos dentro de el, de ser así Desplegamos cada uno de ellos. De otra manera Desplegamos Árbol Vació.
  • 80. 78 Algoritmo: Recorrido(Arbol, N) Si N ≠ 0 i -> Mientras i < N Imprimir Arbol[i] i -> i + 1 //Fin del ciclo// Salir //Fin de la condición// Imprimir "Arbol Vacio..." Salir Corrida:
  • 81. 79 #include <conio.h> #include <iostream.h> class Arbol_Monton { private: int Arbol[25]; int N; public: Arbol_Monton() { for(int i=0;i<25;i++) Arbol[i]=0; N=0; } void Insertar(int a) { if(N<25) { Arbol[N]=a; N++; OrdMon(N); return; } cout<<"Arbol Lleno..."<<endl; } void Eliminar(int a) { int t; if(N!=0) { OrdMon(N); for(int i=0;i<N;i++) { if(Arbol[i]==a) { for(int j=i+1;j<N;j++) { t=Arbol[i]; Arbol[i]=Arbol[j]; Arbol[j]=t; } N--; cout<<"Elemento Eliminado..."<<endl; return; } } } cout<<"Arbol Vacio... Imposible Eliminar..."<<endl; } void Busqueda(int a) { if(N!=0) { OrdMon(N); for(int i=0;i<N;i++) if(Arbol[i]==a) { cout<<"Elemento Encontrado..."<<endl; return; } cout<<"El Elemento no esta en el Arbol..."<<endl; return; } cout<<"Arbol Vacio..."<<endl; } void OrdMon(int n) { ConstMon(n); while(n>1) { n--; Burbuja(0,n); RecMon(n,0); } } void ConstMon(int n) { for(int v=n/2- 1;v>=0;v--) RecMon(n,v); } void RecMon(int n,int v) { int w=2*v+1; while(w<n) { if(w+1<n) if (Arbol[w+1]>Arbol[w]) w++; if(Arbol[v]>=Arbol[w]) return; Burbuja(v,w); v=w; w=2*v+1; } } void Burbuja(int i,int j) { int t=Arbol[i]; Arbol[i]=Arbol[j]; Arbol[j]=t; } void Recorrido() { if(N!=0) { for(int i=0;i<N;i++) cout<<Arbol[i]<<endl; return; } cout<<"Arbol Vacio..."<<endl; } }tec; main() { int res,op=0; while(op!=5) { clrscr(); cout<<"n1) Recorridon2) Busquedan3) Insercionn4) Eliminarn5) Salir"<<endl; gotoxy(1,1); cout<<"Que deseas hacer?: "; cin>>op; gotoxy(1,10);
  • 82. 80 switch (op) { case 1: tec.Recorrido(); break; case 2: cout<<"Que Numero deseas buscar?"<<endl; cin>>res; tec.Busqueda(res); break; case 3: cout<<"Que Numero quieres Insertar?"<<endl; cin>>res; tec.Insertar(res); break; case 4: cout<<"Que Numero quieres Eliminar?"<<endl; cin>>res; tec.Eliminar(res); break; case 5: cout<<"Salida..."; break; default: cout<<"Opcion Erronea"<<endl; break; } getch(); } }
  • 83. 81 Unidad 6: Ordenamientos Internos Introducción: En esta Unidad explicaremos 4 algoritmos para el Ordenamiento de Arreglos en Memoria Ram. A continuación mencionaremos los diferentes métodos para ordenar: 1. Burbuja 2. ShellSort 3. RadixSort 4. QuickSort Burbuja El método de la burbuja es una comparación lineal con cada uno de los elementos, el elemento que sea menor contra el que se está comparado intercambiaran posiciones. Este método no es recomendado para grandes comparaciones, ya que es un proceso muy lento y requiere de una gran cantidad de Memoria Ram. Programa: #include<conio.h> #include<iostream. h> class Lista { private: int Lista[10],N; public: Lista() { for(int i=0;i<10;i++) Lista[i]=0; N=0; } void Burbuja(void) { if(N!=0) { int i,j,aux; for(i=0;i<9;i++) for(j=i+1;j<10; j++) if(Lista[i]<Lista[ j]) { aux=Lista[i]; Lista[i]=Lista[j]; Lista[j]=aux; } cout<<"Lista Ordenada..." <<endl; return; } cout<<"Lista Vacia..."<<endl; } void Busqueda(int Elem) { if(N!=0) { for(int i=0;i<N;i++) if(Lista[i]==Elem) { cout<<"El "<<Elem<<" esta en la Lista"<<endl; return; } } cout<<"Lista Vacia..."<<endl; return; } void Insertar(int Elem) { if(N<10) { Lista[N]=Elem; N++; cout<<"El "<<Elem<<" fue Insertado"<<endl; return; } cout<<"Lista Llena... Imposible Insertar"<<endl; return; } void Eliminar(int
  • 84. 82 Elem) { if(N!=0) { for(int i=0;i<N;i++) if(Lista[i]==Elem) { Lista[i]=0; Burbuja(); N--; return; } } cout<<"Lista Vacia... Imposible Eliminar..." <<endl; return; } void Recorrido() { if(N!=0) { for(int i=0;i<N;i++) cout<<Lista[i] <<endl; } cout<<"Lista Vacia..."<<endl; } }tec; main() { int op=0,res; while(op!=6) { clrscr(); cout<<"n1) Recorridon2) Ordenarn3) Busquedan4) Insercionn5) Eliminar un Daton6) Salir"<<endl; gotoxy(1,1); cout<<"Que deseas hacer: "; cin>>op; gotoxy(1,10); switch (op) { case 1: tec.Recorrido(); break; case 2: tec.Burbuja(); break; case 3: cout<<"Que Numero de Control deseas buscar?"<<endl; cin>>res; tec.Busqueda(res); break; case 4: cout<<"Que Numero Deseas Insertar?"<<endl; cin>>res; tec.Insertar(res); break; case 5: cout<<"Que Numero de Control deseas Eliminar?"<<endl; cin>>res; tec.Eliminar(res); break; case 6: cout<<"Salida..."; break; default: cout<<"Opcion Erronea"<<endl; break; } getch(); } }
  • 85. 83 ShellSort Esta forma de ordenación es muy parecida a la ordenación con burbuja. La diferencia es que no es una comparación lineal, sino que trabaja con una segmentación entre los datos. Por lo tanto es un buen método, pero no el mejor para implementarlos en grandes arreglos. Programa: #include<conio.h> #include<iostream. h> class Lista { private: int Lista[10],N; public: Lista() { for(int i=0;i<10;i++) Lista[i]=0; N=0; } void ShellSort(void) { if(N!=0) { int salto,aux,i; for(salto=6/2; salto!=0;salto/=2) { for(i=salto;i<6; i++) if(Lista[i- salto]<Lista[i]) { aux=Lista[i]; Lista[i]=Lista[i- salto]; Lista[i- salto]=aux; } } cout<<"Lista Ordenada..." <<endl; return; } cout<<"Lista Vacia..."<<endl; } void Busqueda(int Elem) { if(N!=0) { for(int i=0;i<N;i++) if(Lista[i]==Elem) { cout<<"El "<<Elem<<" esta en la Lista"<<endl; return; } } cout<<"Lista Vacia..."<<endl; return; } void Insertar(int Elem) { if(N<10) { Lista[N]=Elem; N++; cout<<"El "<<Elem<<" fue Insertado"<<endl; return; } cout<<"Lista Llena... Imposible Insertar"<<endl; return; } void Eliminar(int Elem) { if(N!=0) { for(int i=0;i<N;i++) if(Lista[i]==Elem) { Lista[i]=0; ShellSort(); N--; return; } } cout<<"Lista Vacia... Imposible Eliminar..." <<endl; return; } void Recorrido() { if(N!=0) { for(int i=0;i<N;i++)
  • 86. 84 cout<<Lista[i] <<endl; } cout<<"Lista Vacia..."<<endl; } }tec; main() { int op=0,res; while(op!=6) { clrscr(); cout<<"n1) Recorridon2) Ordenarn3) Busquedan4) Insercionn5) Eliminar un Daton6) Salir"<<endl; gotoxy(1,1); cout<<"Que deseas hacer: "; cin>>op; gotoxy(1,10); switch (op) { case 1: tec.Recorrido(); break; case 2: tec.ShellSort(); break; case 3: cout<<"Que Numero de Control deseas buscar?"<<endl; cin>>res; tec.Busqueda(res); break; case 4: cout<<"Que Numero Deseas Insertar?"<<endl; cin>>res; tec.Insertar(res); break; case 5: cout<<"Que Numero de Control deseas Eliminar?"<<endl; cin>>res; tec.Eliminar(res); break; case 6: cout<<"Salida..."; break; default: cout<<"Opcion Erronea"<<endl; break; } getch(); } }
  • 87. 85 RadixSort Este ordenamiento se basa en los valores de los dígitos reales en las representaciones de posiciones de los números que se ordenan. Es decir… toma un número y lo descompone en sus unidades, decenas, centenas, etc… de esta manera va determinando las posiciones de cada uno de ellos. Programa: #include <math.h> #include <conio.h> #include <iostream.h> class Lista { private: int Lista[10],Temp[10] ,Elementos,N; public: Lista() { for(int i=0;i<10;i++) Lista[i]=0; N=9; Elementos=0; } void Ordenar() { if(N!=9) { RadixSort(0,Elemen tos,Lista,Temp); RadixSort(1,Elemen tos,Temp,Lista); RadixSort(2,Elemen tos,Lista,Temp); RadixSort(3,Elemen tos,Temp,Lista); cout<<"Lista Ordenada..." <<endl; return; } cout<<"Lista Vacia..."<<endl; } void RadixSort (int byte, int N, int *fuente, int *dest) { int cont[256]; int ind[256]; int i; memset(cont,0,size of(cont)); for(i=0;i<10;i++) cont[((fuente[i]) >>(byte*8))&0xff] ++; ind[0]=0; for(i=1;i<256;i++) ind[i]=ind[i- 1]+cont[i-1]; for(i=0;i<10;i++) dest[ind[((fuente[ i])>>(byte*8))&0xf f]++]=fuente[i]; } void Busqueda(int Elem) { if(N!=9) { for(int i=0;i<N;i++) if(Lista[i]==Elem) { cout<<"El "<<Elem<<" esta en la Lista"<<endl; return; } } cout<<"Lista Vacia..."<<endl; return; } void Insertar(int Elem) { if(N!=-1) { Elementos++; Lista[N]=Elem; N--; cout<<"El "<<Elem<<" fue Insertado"<<endl; return; } cout<<"Lista Llena... Imposible Insertar"<<endl; return; } void Eliminar(int Elem) { if(N!=9) { for(int i=0;i<N;i++) if(Lista[i]==Elem) {