Sunteți pe pagina 1din 54

Universidad de Panam

Facultad de Informtica, Electrnica y Comunicacin

Licenciatura en Ingeniera en Informtica

PROGRAMACION II
ESTRUCTURAS DE DATOS

Integrantes: Diogo Lopes

EC-4210444
Roque Solis
8-798-6

Miguel Pinto

8-8751805

INDICE
INTRODUCIN.............................................................................................
...........................3
ARREGLO....................................................................................................
............................4
ARREGLO
UNIMENSIONALES......................................................................................
5
EJEMPLO......................................................................................................
...6
ARREGLO
MULTIDIMENSIONALES..............................................................................7
EJEMPLO......................................................................................................
...8
PILA.............................................................................................................
...........................8
OPERACIONES.............................................................................................
................9
EJEMPLO......................................................................................................
...............9
COLA...........................................................................................................
..........................12
OPERACIONES
...12
EJEMPLO
...12
LISTA
.15
LISTAS SIMPLEMENTE
ENLAZADA.....16
CARACTERISTICA
...16

EJEMPLO
.....17
LISTAS DOBLEMENTE
ENLAZADAS...................................22
EJEMPLO......................................................................................................
.25
LISTAS
CIRCULARES...............................................................................................
...28
EJEMPLOS....................................................................................................
.28
ARBOLES.....................................................................................................
..........................31
CARACTERISTICAS Y
FUNCIONAMENTO...................................................................32
TIPOS DE
ARBOLES...................................................................................................3
3
ARBOL
BINARIO......................................................................................................
..33
EJEMPLO......................................................................................................
.34
GRAFOS......................................................................................................
..........................39
FORMAS DE
REPRESENTACION................................................................................39
GENERADORES...........................................................................................
..............40
CONSTRUCTORES.......................................................................................
..............40
SELECTORES...............................................................................................
...............41
EJEMPLO......................................................................................................
.............41

METDOS DE
ORDENAMIENTO.........................................................................................
..44
ORDENAMIENTO DE
BURBUJA.................................................................................45
EJEMPLO......................................................................................................
.45
ORDENAMIENTO
SHELL............................................................................................46
EJEMPLO......................................................................................................
.46
ORDENAMIENTO POR
INSERCCIN..........................................................................47
EJEMPLO......................................................................................................
.47
ORDENAMIENTO POR
SELECCIN............................................................................48
EJEMPLO......................................................................................................
.49
1. INTRODUCIN
Una de las aplicaciones ms interesantes y potentes de la memoria dinmica y de los
punteros son, sin duda, las estructuras dinmicas de datos. Las estructuras bsicas
disponibles en C y C++ (structs y arrays) tienen una importante limitacin: no pueden
cambiar de tamao durante la ejecucin. Losarrays estn compuestos por un
determinado nmero de elementos, nmero que se decide en la fase de diseo, antes
de que el programa ejecutable sea creado.
En muchas ocasiones se necesitan estructuras que puedan cambiar de tamao durante
la ejecucin del programa. Por supuesto, podemos crear arraysdinmicos, pero una
vez creados, tu tamao tambin ser fijo, y para hacer que crezcan o disminuyan de
tamao, deberemos reconstruirlos desde el principio.
Las estructuras dinmicas nos permiten crear estructuras de datos que se adapten a las
necesidades reales a las que suelen enfrentarse nuestros programas. Pero no slo eso,
como veremos, tambin nos permitirn crear estructuras de datos muy flexibles, ya sea

en cuanto al orden, la estructura interna o las relaciones entre los elementos que las
componen.
Las estructuras de datos estn compuestas de otras pequeas estructuras a las que
llamaremos nodos o elementos, que agrupan los datos con los que trabajar nuestro
programa y adems uno o ms punteros autoreferenciales, es decir, punteros a objetos
del mismo tipo nodo.

2. ARREGLO
Un arreglo o array es una coleccin de variables relacionadas a las que
se hace referencia por medio de un nombre comn. Otra definicin
vlida es que un arreglo es un conjunto de datos que se almacenan en
memoria de manera contigua con el mismo nombre y para diferenciar
los elementos de un arreglo se utiliza un ndice. En el lenguaje C++ un
arreglo se le conoce como un tipo de dato compuesto. Los arreglos
pueden tener una o varias dimensiones.

ndice de un arreglo: Todo arreglo est compuesto por un nmero de


elementos. El ndice es un nmero correlativo que indica la posicin de
un elemento del arreglo. Los ndices en C++ van desde la posicin 0
hasta la posicin tamao 1.
Elemento de un arreglo: Un elemento de un arreglo es un valor
particular dentro de la estructura del arreglo. Para acceder a un

elemento del arreglo es necesario indicar la posicin o ndice dentro del


arreglo.
Ejemplo:
arreglo[0] //Primer elemento del arreglo
arreglo[3] //Cuarto elemento del arreglo
2.1

ARREGLOS UNIDIMENSIONALES

Un arreglo de una dimensin es una lista de variables, todas de un


mismo tipo a las que se hace referencia por medio de un nombre
comn. Una variable individual del arreglo se llama elemento del
arreglo. Para declarar un arreglo de una sola dimensin se usa el
formato general:
tipo_dato identificador[tamao];
Un elemento del arreglo se accede indexando el arreglo por medio de un
nmero del elemento. En C++ todos los arreglos empiezan en 0, esto
quiere decir que si se desea acceder al primer elemento del arreglo debe
usar el ndice igual a 0. Para indexar un arreglo se especifica el ndice del
elemento que interesa dentro de un corchete, ejemplo: valor =
arreglo[1];
Los arreglos empiezan en 0, de manera que el ndice 1 se refiere al
segundo elemento. Para asignar el valor a un elemento de un arreglo,
ponga el elemento en el lado izquierdo de una sentencia de asignacin:
arreglo[0] = 100;
C++ almacena arreglos de una sola dimensin en una localizacin de
memoria contigua con el primer elemento en la posicin ms baja. De
esta manera, arreglo[0] es adyacente a arreglo[1], que es adyacente a
arreglo[2] y as sucesivamente. Puede usar el valor de un elemento de
un arreglo donde quiera que usara una variable sencilla o una
constante.
2.1.1 EJEMPLO
Ejemplo algoritmo: Arreglo de una dimensin
Declaracin
int arreglo[3]; // forma un arreglo de una dimensin y de tres
elementos
Nombre del arreglo
arreglo
Nombre de los elementos
arreglo[0] primer elemento
arreglo[1] segundo elemento
arreglo[2] tercer elemento

Ejemplo C++: el siguiente programa carga el arreglo sqrs con los


cuadrados de los nmeros del 1 al 10 y luego los visualiza.
using namespace std;
#include
int main()
{
int sqrs[10];
int i;
for (i=1; i<11; i++){
sqrs[i-1]=i*i;
}
for (i=0; i<10; i++){
cout<<sqrs[i]<<endl;
}
return 0;
}
//La forma como se almacenan los valores en el arreglo es la siguiente:
sqrs[0] = 1*1
sqrs[1] = 2*2
sqrs[2] = 3*3
sqrs[3] = 4*4
sqrs[4] = 5*5
sqrs[5] = 6*6
sqrs[6] = 7*7
sqrs[7] = 8*8
sqrs[8] = 9*9
sqrs[9] = 10*10
2.2

ARREGLOS MULTIDIMENSIONALES

Es una estructura de datos esttica y de un mismo tipo de datos, y de


longitud fija que almacena datos de forma matricial. De igual forma que
los arreglos unidimensionales, el almacenamiento de los datos en la
memoria se realiza de forma secuencial y son accedidos mediante
ndices. Los arreglos multidimensionales son tambin conocidos como
matrices. Por lo tanto se llama matriz de orden "mn" a un conjunto
rectangular de elementos dispuestos en filas "m" y en columnas "n",
siendo m y n nmeros naturales. Las matrices se denotan con letras
maysculas: A, B, C, ... y los elementos de las mismas con letras
minsculas y subndices que indican el lugar ocupado: a, b, c, ... Un
elemento genrico que ocupe la fila i y la columna j se escribe i,j. Si el
elemento genrico aparece entre parntesis tambin representa a toda
la matriz: A (i,j).

Una matriz de orden 3x4 se muestra a continuacin, siendo M una


matriz de 3 filas y 4 columnas, la representacin grfica de sus
posiciones sera la siguiente:
M 3x4 Filas = 3, columnas = 4

Matrices cuadradas: Una matriz cuadrada es una matriz que tiene el


mismo nmero de filas y columnas. La matriz que se muestra a
continuacin es de orden 3x3.

2.2.1 EJEMPLO
ALGORITIMO: Arreglo de dos dimensiones de orden 2x3.
char m[2][3] ;

Declaracin
char m[2][3]; // forma una tabla de dos filas y tres columnas
// cada fila es un arreglo de una dimensin
// la declaracin indica que hay dos arreglos de una dimensin
Nombre del grupo
m indica la localizacin del grupo en la memoria
Nombre de las filas
m[0] primera fila indica la localizacin de la fila dentro del
grupo
m[1] segunda fila indica la localizacin de la fila dentro del
grupo
Nombre de los elementos
m[0][0] primer elemento
m[0][1] segundo elemento
m[0][2] tercer elemento

m[1][0] cuarto elemento


m[1][1] quinto elemento
m[1][2] sexto elemento
CODIGO C++ Llenado de un arreglo de enteros de dimensin 3x2. En
este ejemplo el llenado lo realiza el usuario, en otros ejemplos se ver
como realizar llenado de matrices mediante asignacin automtica,
clculos de operaciones, etc.
#include <iostream>
using namespace std;
int main()
{
int matriz [3][2];
int valor;
for(int i=0;i<3;i++) // Recorre las filas de la matriz
{
for(int j=0; j<2;j++) // Recorre las columnas de la matriz
{
cout<<"Ingrese el valor de la matriz en la posicion
["<<i<<","<<j<<"]"<<endl;
cin>>valor;
matriz[i][j] = valor;
}
}
// Imprimiendo el arreglo en formato matricial
for(int i=0;i<3;i++)
{
cout<<"|";
for(int j=0; j<2;j++)
{
cout<<"\t"<<matriz[i][j]<<"\t";
}
cout<<"|"<<endl;
}
return 0;
}
3. PILA
Pila es una coleccin de datos a los cuales se les puede acceder
mediante un extremo, que se conoce generalmente como tope.

Una pila representa una estructura lineal de datos en que se puede


agregar o quitar elementos nicamente por uno de los dos extremos. En
consecuencia, los elementos de una pila se eliminan en el orden inverso
al que se insertaron. Debido a esta caracterstica, se le conoce como
estructura LIFO (last input, first output).
Existen muchos casos prcticos en los que se utiliza la idea de pila:
Ejemplo; pila de platos, en el supermercado latas.
Las pilas con estructuras lineales como los arreglos, ya que sus
componentes ocupan lugares sucesivos y cada uno tienen un nico
sucesor, con excepcin del primero/ltimo.
Al utilizar arreglos para implementar pilas se tiene la limitacin de que
se debe reservar el espacio en memoria con anticipacin. Una vez dado
un mximo de capacidad a la pila no es posible insertar un nmero de
elementos mayor que el mximo establecido. Si esto ocurre, en otras
palabras si la pila est llena y se intenta insertar un nuevo elemento, se
producir un error conocido como desbordamiento overflow.
3.1

OPERACIONES

Operaciones con pilas


Insertar un elemento (push)
Eliminar (pop)
Pila_vaca
Pila_llena
Las pilas tienen un conjunto de operaciones muy limitado, las
operaciones fundamentales son de "push" y "pop":
- Aadir elementos en la cima (Push): pondr un nuevo elemento en la
parte superior de la pila.
- Eliminar elementos de la cima (Pop): lo que har ser devolver el
elemento superior de la cima y eliminarlo de la pila.
- Comprobar si la pila est vaca (PilaVacia): Esta operacin es necesaria
para poder decidir si es posible eliminar elementos de la pila.
- Comprobar si la pila est llena (PilaLlena): Esta operacin es necesaria
para poder decidir si es posible insertar ms elementos en la pila.
3.2

EJEMPLO:

ALGORITMO
Pila_vacia
si (tope=0)

ban=0

//pila esta vacia

ban=0

//pila no esta vacia

si no
fin si
Pila_llena
si (tope=max)
ban=0
si no
ban=1
fin si

//pila esta llena


// pila no esta llena

Insertar_pila
Si (ban=1
tope tope+1;
pila[tope]=dato;
si no
Imprimir Pila llena
fin si
Eliminar_pila
si (ban=1)
del_dato lista[tope];
tope tope-1;
si no
Imprimir Pila vacia;
fin si
CODIGO C++
include <stdio.h>
#include <stdlib.h>
#define max 3
int dato[max];
int tope=0;
int op;
void mostrar(void){
printf("\n");
for(int temp=tope-1;temp >=0 ;temp--)
{
printf("Em la posicion %d tenemos %d\n",temp,dato[temp]);
}
printf("\n");
system("PAUSE");

}
void insertar(void){
if (tope==max){
printf("La pila esta llena, OverFlow\n");
}
else {
printf("Digite el valor para entrar em la pila: \n");
scanf("%d",&dato[tope]);
topo++;
}
mostrar();
}
void eliminar(void){
if (tope==0){
printf("\nLa pila esta vacia\n");
}
else {
printf("\Sacado el valor %d de la pila\n",dato[tope-1]);
tope--;
}
exibir();
}
int menu(){
printf(" Para insertar digite
1\n");
printf(" Para eliminar digite
2\n");
printf(" Para mostrar digite
3\n\n");
printf(" Para salir
4\n");
scanf("%d",&op);
switch (op){
case 1 : insertar();
break;
case 2 : eliminar();
break;
case 3 : mostrar();
break;
}
return 0;
}
int main(){
while (op!=4){
system("cls");
menu();
}

return 0;
}

4. COLA
Una cola es una estructura de datos de acceso restrictivo a sus
elementos. Un ejemplo sencillo es la cola del cine o del autobs, el
primero que llegue ser el primero en entrar, y afortunadamente en un
sistema informtico no se cuela nadie salvo que el programador lo diga.

Es una estructura de datos lineal en la que los nuevos elementos se


introducen por un extremo y se elimina por otro extremo. Es importante
sealar que los elementos se eliminan en mismo orden que se
insertaron. La posicin del primero elemento en la cola se llama frente,
la posicin en ltimo se llama final.

Las colas sern de ayuda fundamental para ciertos recorridos de rboles


y grafos.

Las colas ofrecen dos operaciones fundamentales, que son encolar (al
final de la cola) y desencolar (del comienzo de la cola). Al igual que con
las pilas, la implementacin de las colas suele encapsularse, es decir,
basta con conocer las operaciones de manipulacin de la cola para
poder usarla, olvidando su implementacin interna.

Es una estructura de tipo FIFO (First In First Out), es decir: primero en


entrar, primero en salir.
4.1

OPERACIONES

Limpiar Cola
Cola Vaca

Cola Llena
Insertar Cola
Eliminar Cola

4.2

EJEMPLOS

ALGORITMO
INSERTAR
insertar (cola, max, final, frente, dato)
si (final<max)
final <- final+1
cola[final] <- dato
si (final=1) //insertar en primero elemento
frente<-1
fin_si
si no
imprimir cola desbordamiento
fin_si
ELIMINAR
eliminar (cola, frente, final, dato)
si (frente!=0)
//tiene elemento
dato <- cola[frente]
si (frente=final) //hay um solo elemento
frente <- 0
final <- 0 //cola vacia
si no
frente <- frente+1
fin_si
si no
imprimir Cola vacia
fin_si
COLA VACIA
cola_vacia (cola, frente, band)
si (frente=0)
band <- 1
si no
band <- 0
fin_si
COLA LLENA
cola_llena (cola, final, max, band)
si (final=max)
band <- 1

si no
band <- 0
fin_si
CODIGO EN C++
#include <stdio.h>
#define MAX 20
int pila[MAX], cola[MAX],ind=0,idxc=0;
int borrar(){
if (ind==0) printf("Error Pila esta vacia");
else {
ind--;
return pila[ind];
}
}
int borrar_cola(){
int m,n;
if (idxc==0) printf("Error Cola esta vacia");
else {
m = cola[0]; // elemento que sale
for (n=0;n<idxc-1;n++)
cola[n]=cola[n+1];
idxc--;
return m;
}
}
void insertar(int d){
if (ind==MAX) {
printf("Error Pila llena ");
getch();
}
else {
pila[ind]=d;
ind++;
}
}
void insertar_c(int d){
if (idxc==MAX) printf("Error Cola llena ");
else {

cola[idxc]=d;
idxc++;
}
}
int main()
{
int x=1,y,z,j;
while (x!=0) {
system("cls");
printf("1. insertar pila \n");
printf("2. borrar en pila \n");
printf("3. listar pila \n");
printf("4. insertar en cola \n");
printf("5. borrar en cola \n");
printf("6. listar cola \n");
printf("0. Salir \n");
scanf("%d",&x);
switch(x)
{
case 1: printf("digite su dato: ");
scanf("%d",&z);
insertar(z);
break;
case 2: printf("dato borrado: %d",borrar());
getch();
break;
case 3: for (j=0;j<=ind-1; j++) printf("%d - ",pila[j]);
getch();
break;
case 4: printf("digite su dato: ");
scanf("%d",&z);
insertar_c(z);
break;
case 5: printf("dato borrado: %d",borrar_cola());
getch();
break;
case 6: for (j=0;j<=idxc -1; j++) printf("%d - ",cola[j]);
getch();
break;
}
}
}
5. LISTAS

Es una estructura de datos representada hasta el momento por un


arreglo, a pesar de un arreglo ser esttico. Ese tipo de estructura es de
tipo lineal y dinmica. Es lineal porque cada elemento le puede seguir
solo a otro elemento. Es dinmica porque se puede manejar la memoria
de manera no flexible sin necesidad de reservar espacio con antelacin.
Se clasifican en 3 tipos: Listas simplemente ligada, doblemente ligada y
listas circulares.
Las listas de C++ son secuencias de elementos almacenados en una
lista encadenada. Comparadas con los vectores, estas permiten una
mayor rapidez de insercin y borrado, pero una menor velocidad de
acceso aleatorio.
5.1

LISTAS SIMPLEMENTE ENLAZADA

Una lista enlazada es un conjunto de elementos llamados nodos en los


que cada uno de ellos contiene un dato y tambin la direccin del
siguiente nodo, donde el orden de los mismos se establece mediante
punteros.
La idea bsica es que cada componente de la lista incluya un
puntero que indique donde puede encontrarse el siguiente componente
por lo que el orden relativo de estos puede ser fcilmente alterado
modificando los punteros lo que permite, a su vez, aadir o suprimir
elementos de la lista. El primer elemento de la lista es la cabecera, que
slo contiene un puntero que seala el primer elemento de la lista.
El ltimo nodo de la lista apunta a NULL (nulo) porque no hay ms nodos
en la lista. Se usar el trmino NULL para designar el final de la lista.

5.1.1 CARACTERISTICAS

RECORRIDO Esta operacin consiste en visitar cada uno de los nodos


que forman la lista. Para recorrer todos los nodos de la lista, se comienza
con el primero, se toma el valor del campo liga para avanzar al segundo
nodo, el campo liga de este nodo nos dar la direccin del tercer nodo, y
as sucesivamente.

INSERCIN Esta operacin consiste en agregar un nuevo nodo a la


lista. Para esta operacin se pueden considerar tres casos:
Insertar un nodo al inicio.
Insertar un nodo antes o despus de cierto nodo.
Insertar un nodo al final.
BORRADO La operacin de borrado consiste en quitar un nodo de la
lista, redefiniendo las ligas que correspondan. Se pueden presentar
cuatro casos:
Eliminar el primer nodo.
Eliminar el ltimo nodo.
Eliminar un nodo con cierta informacin.
Eliminar el nodo anterior o posterior al nodo cierta con
informacin.
BUSQUEDA Esta operacin consiste en visitar cada uno de los nodos,
tomando al campo liga como puntero al siguiente nodo a visitar.

5.1.2 EJEMPLO
#include <iostream>
#include <stdlib.h>
using namespace std;
struct nodo{
int nro;
// en este caso es un numero entero
struct nodo *sgte;
};
typedef struct nodo *Tlista;
void insertarInicio(Tlista &lista, int valor)
{
Tlista q;
q = new(struct nodo);
q->nro = valor;
q->sgte = lista;
lista = q;
}

void insertarFinal(Tlista &lista, int valor)


{
Tlista t, q = new(struct nodo);
q->nro = valor;
q->sgte = NULL;
if(lista==NULL)
{
lista = q;
}
else
{
t = lista;
while(t->sgte!=NULL)
{
t = t->sgte;
}
t->sgte = q;
}
}
int insertarAntesDespues()
{
int _op, band;
cout<<endl;
cout<<"\t 1. Antes de la posicion
cout<<"\t 2. Despues de la posicion
cout<<"\n\t Opcion : "; cin>> _op;
if(_op==1)
band = -1;
else
band = 0;
return band;
}

"<<endl;
"<<endl;

void insertarElemento(Tlista &lista, int valor, int pos)


{
Tlista q, t;
int i;
q = new(struct nodo);
q->nro = valor;
if(pos==1)
{
q->sgte = lista;
lista = q;
}
else

{
int x = insertarAntesDespues();
t = lista;
for(i=1; t!=NULL; i++)
{
if(i==pos+x)
{
q->sgte = t->sgte;
t->sgte = q;
return;
}
t = t->sgte;
}
}
cout<<" Error...Posicion no encontrada..!"<<endl;
}
void buscarElemento(Tlista lista, int valor)
{
Tlista q = lista;
int i = 1, band = 0;
while(q!=NULL)
{
if(q->nro==valor)
{
cout<<endl<<" Encontrada en posicion "<< i <<endl;
band = 1;
}
q = q->sgte;
i++;
}
if(band==0)
cout<<"\n\n Numero no encontrado..!"<< endl;
}
void reportarLista(Tlista lista)
{
int i = 0;
while(lista != NULL)
{
cout <<' '<< i+1 <<") " << lista->nro << endl;
lista = lista->sgte;
i++;
}
}

void eliminarElemento(Tlista &lista, int valor)


{
Tlista p, ant;
p = lista;
if(lista!=NULL)
{
while(p!=NULL)
{
if(p->nro==valor)
{
if(p==lista)
lista = lista->sgte;
else
ant->sgte = p->sgte;
delete(p);
return;
}
ant = p;
p = p->sgte;
}
}
else
cout<<" Lista vacia..!";
}
void eliminaRepetidos(Tlista &lista, int valor)
{
Tlista q, ant;
q = lista;
ant = lista;
while(q!=NULL)
{
if(q->nro==valor)
{
if(q==lista) // primero elemento
{
lista = lista->sgte;
delete(q);
q = lista;
}
else
{
ant->sgte = q->sgte;
delete(q);
q = ant->sgte;
}

}
else
{
ant = q;
q = q->sgte;
}
}// fin del while
cout<<"\n\n Valores eliminados..!"<<endl;
}
void menu1()
{
cout<<"\n\t\tLISTA ENLAZADA SIMPLE\n\n";
cout<<" 1. INSERTAR AL INICIO
"<<endl;
cout<<" 2. INSERTAR AL FINAL
"<<endl;
cout<<" 3. INSERTAR EN UNA POSICION
"<<endl;
cout<<" 4. REPORTAR LISTA
"<<endl;
cout<<" 5. BUSCAR ELEMENTO
"<<endl;
cout<<" 6. ELIMINAR ELEMENTO 'V'
"<<endl;
cout<<" 7. ELIMINAR ELEMENTOS CON VALOR 'V' "<<endl;
cout<<" 8. SALIR
"<<endl;
cout<<"\n INGRESE OPCION: ";
}
/*
Funcion Principal
---------------------------------------------------------------------*/
int main()
{
Tlista lista = NULL;
int op;
// opcion del menu
int _dato; // elemenento a ingresar
int pos; // posicion a insertar
system("color 0b");
do
{
menu1(); cin>> op;
switch(op)
{
case 1:
cout<< "\n NUMERO A INSERTAR: "; cin>> _dato;
insertarInicio(lista, _dato);
break;

case 2:
cout<< "\n NUMERO A INSERTAR: "; cin>> _dato;
insertarFinal(lista, _dato );
break;
case 3:
cout<< "\n NUMERO A INSERTAR: ";cin>> _dato;
cout<< " Posicion : ";
cin>> pos;
insertarElemento(lista, _dato, pos);
break;
case 4:
cout << "\n\n MOSTRANDO LISTA\n\n";
reportarLista(lista);
break;
case 5:
cout<<"\n Valor a buscar: "; cin>> _dato;
buscarElemento(lista, _dato);
break;
case 6:
cout<<"\n Valor a eliminar: "; cin>> _dato;
eliminarElemento(lista, _dato);
break;
case 7:
cout<<"\n Valor repetido a eliminar: "; cin>> _dato;
eliminaRepetidos(lista, _dato);
break
}
cout<<endl<<endl;
system("pause"); system("cls");
}while(op!=8);
system("pause");
return 0;
}
5.2

LISTA DOBLEMENTE ENLAZADA

Una lista doblemente enlazada es una lista lineal en la que cada nodo
tiene dos enlaces: uno apunta al nodo anterior, o apunta al valor NULL o a
la lista vaca si es el primer nodo; y otro que apunta al siguiente nodo
siguiente, o apunta al valor NULL o a la lista vaca si es el ltimo nodo.

Las listas doblemente enlazadas no necesitan un nodo especial para


acceder a ellas, pueden recorrerse en ambos sentidos a partir de
cualquier nodo, esto es porque a partir de cualquier nodo, siempre es
posible alcanzar cualquier nodo de la lista, hasta que se llega a uno de
los extremos.

Dentro del tipo abstracto de listas doblemente enlazadas podemos


proponer las siguientes primitivas:
Inicializacin
Esta operacin tiene que ser hecha antes de otra operacin sobre la
lista.
Esta empezar indicando el puntero inicio y tambin el puntero fin con el
puntero NULL y, adems, el tamao con el valor 0.
Insercin en una lista vaca
Las etapas son las siguientes: asignacin de memoria para el nuevo
elemento, llenado del campo de datos del nuevo elemento, el
puntero anterior del nuevo elemento apuntar hacia NULL(dado que la
insercin es hecha en una lista vaca utilizamos la direccin del
puntero inicio que vale NULL), el puntero siguiente del nuevo elemento
apuntar hacia NULL (debido a que la insercin es hecha en una lista
vaca se utiliza la direccin del puntero fin que vale NULL), los punteros
de inicio y fin sealarn hacia el nuevo elemento y el tamao es
actualizado.
Insercin al inicio de la lista
Las etapas son las siguientes: asignacin de memoria al nuevo
elemento, rellenado del campo de datos del nuevo elemento, el
puntero anterior del
nuevo
elemento
apunta
hacia NULL,
el
puntero siguiente del nuevo elemento apuntar hacia el primero de los
elementos, el puntero anterior del primer elemento apunta hacia el
nuevo elemento, el puntero inicio apunta hacia el nuevo elemento, el
puntero fin no cambia y el tamao es incrementado.
Insercin al final de la lista
Las etapas son las siguientes: asignacin de memoria al nuevo
elemento, rellenado del campo de datos del nuevo elemento y el
puntero siguiente del nuevo elemento va a apuntar hacia NULL<bold>,
el puntero <bold>anterior del nuevo elemento apunta hacia el ltimo

elemento (es el puntero fin que contiene por ahora su direccin), el


puntero siguiente del ltimo elemento va a apuntar al nuevo elemento,
el puntero fin apunta hacia el nuevo elemento, el puntero inicio no
cambia y el tamao es incrementado.
Insercin antes de un elemento
La insercin se efectuar antes de cierta posicin pasado como
argumento
a
la
funcin.
La posicin indicada no debe ser ni el primer ni el ltimo elemento. En
ese caso hay que utilizar las funciones de insercin al inicio y/o al final
de
la
lista.
Las etapas son las siguientes: asignacin de memoria al nuevo
elemento, rellenado del campo de datos del nuevo elemento, eleccin
de una posicin en la lista (la insercin se har despus de la posicin
elegida), el puntero siguiente del nuevo elemento apunta hacia el
elemento actual, el puntero anterior del nuevo elemento apunta en la
direccin hacia la que apunta el puntero anterior del elemento actual, el
puntero siguiente del elemento que precede al elemento actual
apuntar hacia el nuevo elemento, el puntero anterior del elemento
actual apunta hacia el nuevo elemento, el puntero fin no cambia, el
puntero inicio cambia si la posicin elegida es la posicin 1y el tamao
se incrementa en una unidad.
Insercin despus de un elemento
Las etapas son las siguientes: asignacin de memoria al nuevo
elemento, rellenado del campo de datos del nuevo elemento, eleccin
de una posicin en la lista (la insercin se har despus de la posicin
elegida), el puntero siguiente del nuevo elemento apunta en la direccin
del puntero siguiente del elemento actual (ver la imagen), el
puntero anterior del nuevo elemento apunta hacia el elemento actual, el
puntero anterior del elemento que va despus del elemento actual
apuntar hacia el nuevo elemento, el puntero siguiente del elemento
actual apunta hacia el nuevo elemento, el puntero inicio no cambia, el
puntero fin cambia si la posicin elegida es la posicin del ltimo
elemento (el tamao de la lista) y el tamao se incrementa en una
unidad.
Eliminacin de un elemento
Sin embargo, la eliminacin al inicio y al final de la lista doblemente
enlazada as como antes o despus de un elemento equivale a la
eliminacin en la posicin 0 (cero) o en la posicin N (N = nmero de
elementos
de
la
lista)
o
en
otra
parte
de
la
lista.
En el caso de listas doblemente enlazadas la eliminacin en cualquier
posicin
no
presenta
ningn
problema
gracias
a
los

punteros anterior y siguiente, que permiten conservar el enlace entre los


elementos de la lista. Razn por la cual solo vamos a crear una funcin.
Si deseamos eliminar el elemento al inicio de la lista elegiremos la
posicin cero, Si deseamos eliminar el elemento al final de la lista
elegiremos la posicin N (el nmero de elementos), si deseamos eliminar
cualquier elemento entonces elegimos su posicin en la lista.
Visualizacin de la lista
Para mostrar la lista entera podemos posicionarnos al inicio o al final de
la lista (el puntero inicio o fin lo permitir). Luego utilizando el
puntero siguiente o anterior de cada elemento, la lista es recorrida del
1er al ultimo elemento o del ultimo al 1er elemento.
La condicin para detener es dada por el puntero siguiente del ultimo
elemento que vale NULL en el caso de la lectura del inicio hacia el fin de
la lista, o por el puntero anterior del 1er elemento que vale NULL, en el
caso de una lectura del final hacia el inicio de la lista.
5.2.1 EJEMPLOS
#include <iostream>
using namespace std;
#define ASCENDENTE 1
#define DESCENDENTE 0
class nodo {
public:
nodo(int v, nodo *sig = NULL, nodo *ant = NULL) :
valor(v), siguiente(sig), anterior(ant) {}
private:
int valor;
nodo *siguiente;
nodo *anterior;
friend class lista;
};
typedef nodo *pnodo;
class lista {
public:
lista() : plista(NULL) {}
~lista();
void Insertar(int v);

void Borrar(int v);


bool ListaVacia() { return plista == NULL; }
void Mostrar(int);
void Siguiente();
void Anterior();
void Primero();
void Ultimo();
bool Actual() { return plista != NULL; }
int ValorActual() { return plista-&gt;valor; }
private:
pnodo plista;
};
lista::~lista() {
pnodo aux;
Primero();
while(plista) {
aux = plista;
plista = plista->siguiente;
delete aux;
}
}
void lista::Insertar(int v) {
pnodo nuevo;
Primero();
// Si la lista est vaca
if(ListaVacia() || plista->valor > v) {
// Asignamos a lista un nuevo nodo de valor v y
// cuyo siguiente elemento es la lista actual
nuevo = new nodo(v, plista);
if(!plista) plista = nuevo;
else plista->anterior = nuevo;
}
else {
// Buscar el nodo de valor menor a v
// Avanzamos hasta el ltimo elemento o hasta que el siguiente
tenga
// un valor mayor que v
while(plista->siguiente && plista->siguiente->valor <= v)
Siguiente();
// Creamos un nuevo nodo despus del nodo actual
nuevo = new nodo(v, plista->siguiente, plista);

plista->siguiente = nuevo;
if(nuevo->siguiente) nuevo->siguiente->anterior = nuevo;
}
}
void lista::Borrar(int v) {
pnodo nodo;
nodo = plista;
while(nodo && nodo->valor < v) nodo = nodo->siguiente;
while(nodo && nodo->valor > v) nodo = nodo->anterior;
if(!nodo || nodo->valor != v) return;
// Borrar el nodo
if(nodo->anterior) // no es el primer elemento
nodo->anterior->siguiente = nodo->siguiente;
if(nodo->siguiente) // no el el ltimo nodo
nodo->siguiente->anterior = nodo->anterior;
delete nodo;
}
void lista::Mostrar(int orden) {
pnodo nodo;
if(orden == ASCENDENTE) {
Primero();
nodo = plista;
while(nodo) {
cout << nodo->valor << "-> ";
nodo = nodo->siguiente;
}
}
else {
Ultimo();
nodo = plista;
while(nodo) {
cout << nodo->valor << "-> ";
nodo = nodo->anterior;
}
}
cout << endl;
}
void lista::Siguiente() {
if(plista) plista = plista->siguiente;
}

void lista::Anterior() {
if(plista) plista = plista->anterior;
}
void lista::Primero() {
while(plista && plista->anterior) plista = plista->anterior;
}
void lista::Ultimo() {
while(plista && plista->siguiente) plista = plista->siguiente;
}
int main() {
lista Lista;
Lista.Insertar(20);
Lista.Insertar(10);
Lista.Insertar(40);
Lista.Insertar(30);
Lista.Mostrar(ASCENDENTE);
Lista.Mostrar(DESCENDENTE);
Lista.Primero();
cout << "Primero: " << Lista.ValorActual() << endl;
Lista.Ultimo();
cout << "Ultimo: " << Lista.ValorActual() << endl;
Lista.Borrar(10);
Lista.Borrar(15);
Lista.Borrar(45);
Lista.Borrar(40);
Lista.Mostrar(ASCENDENTE);
Lista.Mostrar(DESCENDENTE);
return 0;
}
5.3

LISTAS CIRCULARES

En una lista enlazada circular, el primer y el ltimo nodo estn unidos


juntos. Esto se puede hacer tanto para listas enlazadas simples como
para las doblemente enlazadas. Para recorrer un lista enlazada circular
podemos empezar por cualquier nodo y seguir la lista en cualquier

direccin hasta que se regrese hasta el nodo original. Desde otro punto
de vista, las listas enlazadas circulares pueden ser vistas como listas sin
comienzo ni fin. Este tipo de listas es el ms usado para dirigir buffers
para ingerir datos, y para visitar todos los nodos de una lista a partir
de uno dado.

A todos los efectos, las listas circulares son como las listas abiertas en
cuanto a las operaciones que se pueden realizar sobre ellas:

Aadir o insertar elementos.

Buscar o localizar elementos.

Borrar elementos.

Moverse a travs de la lista, siguiente.

Cada una de estas operaciones podr tener varios casos especiales, por
ejemplo, tendremos que tener en cuenta cuando se inserte un nodo en
una lista vaca, o cuando se elimina el nico nodo de una lista.
5.3.1 EJEMPLO
#include <iostream>
using namespace std;
class nodo {
public:
nodo(int v, nodo *sig = NULL) {
valor = v;
siguiente = sig;
}
private:
int valor;
nodo *siguiente;
friend class lista;
};
typedef nodo *pnodo;

class lista {
public:
lista() { actual = NULL; }
~lista();
void Insertar(int v);
void Borrar(int v);
bool ListaVacia() { return actual == NULL; }
void Mostrar();
void Siguiente();
bool Actual() { return actual != NULL; }
int ValorActual() { return actual->valor; }
private:
pnodo actual;
};
lista::~lista() {
pnodo nodo;
// Mientras la lista tenga ms de un nodo
while(actual->siguiente != actual) {
// Borrar el nodo siguiente al apuntado por lista
nodo = actual->siguiente;
actual->siguiente = nodo->siguiente;
delete nodo;
}
// Y borrar el ltimo nodo
delete actual;
actual = NULL;
}
void lista::Insertar(int v) {
pnodo Nodo;
// Creamos un nodo para el nuevo valor a insertar
Nodo = new nodo(v);
// Si la lista est vaca, la lista ser el nuevo nodo
// Si no lo est, insertamos el nuevo nodo a continuacin del apuntado
// por lista
if(actual == NULL) actual = Nodo;
else Nodo->siguiente = actual->siguiente;
// En cualquier caso, cerramos la lista circular
actual->siguiente = Nodo;
}

void lista::Borrar(int v) {
pnodo nodo;
nodo = actual;
// Hacer que lista apunte al nodo anterior al de valor v
do {
if(actual->siguiente->valor != v) actual = actual->siguiente;
} while(actual->siguiente->valor != v && actual != nodo);
// Si existe un nodo con el valor v:
if(actual->siguiente->valor == v) {
// Y si la lista slo tiene un nodo
if(actual == actual->siguiente) {
// Borrar toda la lista
delete actual;
actual = NULL;
}
else {
// Si la lista tiene ms de un nodo, borrar el nodo de valor v
nodo = actual->siguiente;
actual->siguiente = nodo->siguiente;
delete nodo;
}
}
}
void lista::Mostrar() {
pnodo nodo = actual;
do {
cout << nodo->valor << "-> ";
nodo = nodo->siguiente;
} while(nodo != actual);
cout << endl;
}
void lista::Siguiente() {
if(actual) actual = actual->siguiente;
}
int main() {
lista Lista;
Lista.Insertar(20);
Lista.Insertar(10);
Lista.Insertar(40);
Lista.Insertar(30);

Lista.Insertar(60);
Lista.Mostrar();
cout << "Lista de elementos:" << endl;
Lista.Borrar(10);
Lista.Borrar(30);
Lista.Mostrar();
cin.get();
return 0;
}
6. ARBOLES
El rbol es una estructura de datos fundamental en la informtica, muy
utilizada en todos sus campos, porque se adapta a la representacin
natural de informaciones homogneas organizadas y de una gran
comodidad y rapidez de manipulacin.
Las estructuras tipo rbol se usan principalmente para representar datos
con una relacin jerrquica entre sus elementos, como son rboles
genealgicos, tablas, etc.
La definicin de un rbol implica una estructura recursiva. Esto es, la
definicin del rbol se refiere a otros rboles. Un rbol con ningn nodo
es un rbol nulo; no tiene raz.

6.1 Caractersticas y Funcionamiento


La representacin y terminologa de los rboles se realiza con las tpicas
notaciones de las relaciones familiares en los rboles genealgicos:
padre, hijo, hermano, ascendente, descendiente, etc.

RAIZ: Todos los rboles que no estn vacos tienen un nico nodo raz.
Todos los dems elementos o nodos derivan o descienden de el. El nodo
Raz no tiene Padre es decir no es hijo de ningn elemento
PADRE: X es padre de Y s y solo s el nodo X apunta a Y. Tambin se dice
que
X
es
antecesor
de
Y.
HIJO: X es hijo de Y, s y solo s el nodo X es apuntado por Y. Tambin se
dice que X es descendiente directo de Y.
HERMANO: Dos nodos sern hermanos si son descendientes directos de
un mismo nodo.
HOJA: Se le llama hoja o Terminal a aquellos nodos que no tienen
ramificaciones (hijos).
NODO: Son los Vrtices o elementos del rbol.
NODO INTERIOR: Es un nodo que no es raz ni Terminal.
GRADO: Es el nmero de descendientes directos de un determinado
nodo.
GRADO DEL ARBOL: Es el mximo grado de todos los nodos del rbol.
NIVEL.: Es el nmero de arcos que deben ser recorridos para llegar a un
determinado nodo. Por definicin la raz tiene nivel 1.
ALTURA. Es el mximo nmero de niveles de todos los nodos del rbol.
Equivale al nivel ms alto de los nodos ms 1.

PESO: Es el nmero de nodos terminales del rbol


LONGITUD DE CAMINO: Es el nmero de arcos que deben ser recorridos

para llegar desde la raz al nodo X. Por definicin la raz tiene longitud de
camino 1, y sus descendientes directos longitud de camino 2 y as
sucesivamente.

6.2 TIPOS DE ARBOLES

rboles Binarios

rbol de bsqueda binario auto-balanceable

rboles AVL

rboles Rojo-Negro

rbol AA

rbol de segmento
rboles Multicamino

rboles B

rbol-B+

rbol-B*

6.3 ARBOLES BINARIOS


Un rbol binario es un rbol en el que ningn nodo puede tener ms de
dos subrboles. En un rbol binario cada nodo puede tener cero, uno o
dos hijos (subrboles). Se conoce el nodo de la izquierda como hijo
izquierdo y el nodo de la derecha como hijo derecho.
Un rbol binario con enraizado es como un grafo que tiene uno de sus
vrtices, llamado raz, de grado no mayor a 2. Con la raz escogida, cada
vrtice tendr un nico padre, y nunca ms de dos hijos. Si rehusamos el
requerimiento de la conectividad, permitiendo mltiples componentes
conectados en el grafo, llamaremos a esta ltima estructura un bosque'.

Un rbol binario sencillo de tamao 9, 4 niveles y altura 3 (altura =


mximo nivel - 1), con un nodo raz cuyo valor es 2.
6.3.1 EJEMPLOS
ALGORITMO

El algoritmo de creacin de un rbol binario es el siguiente:


Procedimiento crear (q:nodo)

Inicio
mensaje("Rama izquierda?")
lee(respuesta)
si respuesta = "si" entonces
new(p)
q(li) <-- nil
crear(p)
en caso contrario
q(li) <-- nil
mensaje("Rama derecha?")

lee(respuesta)
si respuesta="si" entonces
new(p)
q(ld)<--p
crear(p)
en caso contrario
q(ld) <--nil
fin

INICIO
new(p)
raiz<--p
crear(p)
FIN

CODIGO EN C++

#include <iostream.h>
#include <conio.h>
struct arbol
{
int dato;
arbol *i,*d;
}*elemento, *aux, *cabecera, *ant, *aux2, *ant2;

int dato;
int buscar(void);
void insertar(void);
void buscarmenmay(void);
void buscarmaymen(void);
void eliminar(void);
void main(void)
{
int y,opc;
do
{
clrscr();
y=10;
gotoxy(10,y++);
cout<<"0 - Salir";
gotoxy(10,y++);
cout<<"1 - Buscar";
gotoxy(10,y++);
cout<<"2 - Insertar";
gotoxy(10,y);
cout<<"3 - Borrar";
gotoxy(10,y+=5);
cout<<"Cual es su opcion: ";
cin>>opc;
switch(opc)
{
case 0: break;
case 1: cout<<"\n\nDato a buscar: ";
cin>>dato;
if(buscar())
cout<<"\n\nDato existe";
else
cout<<"\n\nDato inexistente";
break;
case 2:
cout<<"\n\nDato a insertar: ";
cin>>dato;
insertar();
cout<<"\n\nDato Insertado";
break;
case 3:
cout<<"\n\nDato a borrar: ";
cin>>dato;
eliminar();

break;
default:
cout<<"\n\nOpcion incorrecta";
}
if(opc) getch();
}while(opc);
}
int buscar(void)
{
if(!cabecera)
{
cout<<"No hay arbol";
return(0);
}
ant=NULL;
aux=cabecera;
while(aux)
{
if (dato==aux->dato)
return(1);
else
{
ant=aux;
if (dato>aux->dato)
aux=aux->d;
else
aux=aux->i;
}
}
return(0);
}
void insertar(void)
{
if(!cabecera){
cabecera=new(arbol);
cabecera->dato=dato;
cabecera->d=NULL;
cabecera->i=NULL;
return;
}
if (!buscar()) {
aux=new(arbol);
aux->dato=dato;

aux->i=NULL;
aux->d=NULL;
if(dato>ant->dato)
ant->d=aux;
else
ant->i=aux;
}
else
cout<<"\n\nDato existente";
}
void buscarmenmay(void){
aux2=aux->d;
ant2=aux;
while(aux2->i)
{
ant2=aux2;
aux2=aux2->i;
}
aux->dato=aux2->dato;
if(aux2->d)
ant2->i=aux2->d;
delete(aux2);
ant2->d=NULL;
}
void buscarmaymen(void){
aux2=aux->i;
ant2=aux;
while(aux2->d)
{
ant2=aux2;
aux2=aux2->d;
}
aux->dato=aux2->dato;
if(aux2->i)
ant2->d=aux2->i;
delete(aux2);
ant2->i=NULL;
}
void eliminar(void) {
if(!buscar()) {
cout<<"\n\nElemento no encontrado.";
return;
}

if(aux->d==NULL && aux->i==NULL) {


if(ant->dato>dato)
ant->i=NULL;
else
ant->d=NULL;
delete(aux);
}
else
if(aux->d!=NULL)
buscarmenmay();
else
buscarmaymen();
cout<<"\n\nElemento Borrado";
}

7 GRAFOS

Un grafo de 6 vrtices y 7aristas.

Un grafo es un objeto matemtico que se utiliza para representar


circuitos, redes, etc. Los grafos son muy utilizados en computacin, ya
que permiten resolver problemas muy complejos.

Un grafo es un conjunto de nodos unidos por un conjunto de lneas o


flechas. Por lo general, los nodos son entes de procesamiento o
estructuras que contienen algn tipo de informacin y las lneas o
flechas son conexiones o relaciones entre estos entes. Si se utilizan
flechas para conectar los nodos decimos que el grafo es dirigido

(tambin llamado digrafo) porque las relaciones entre los nodos tienen
una direccin. En caso contrario el grafo es no dirigido.

En cualquiera de los dos casos, bien sea que se utilicen lneas o flechas,
a estas relaciones se les puede llamar simplemente aristas.
Frecuentemente las aristas tambin tienen algn tipo de informacin
asociada (distancia, costo, confiabilidad, etc.), en cuyo caso estamos en
presencia de un grafo pesado. Las secuencias de aristas forman caminos
o ciclos. Un ciclo es un camino que termina en el mismo nodo donde
comenz. Si el camino recorre todos los nodos del grafo es llamado tour.
El nmero de aristas en un camino es la longitud del camino.

Se dice que un grafo es conexo si se puede llegar desde cualquier nodo


hasta cualquier otro mediante un camino. De lo contrario no es conexo,
pero puede dividirse en componentes conexas, que son subconjuntos de
nodos y aristas del grafo original que si son conexos. Un grafo conexo sin
ciclos es llamado un rbol.
7.2 FORMAS DE REPRESENTACIN
Existen diferentes implementaciones del tipo grafo: con una matriz de
adyacencias (forma acotada) y con listas y multilistas de adyacencia (no
acotadas).

Matriz de adyacencias: se asocia cada fila y cada columna a cada


nodo del grafo, siendo los elementos de la matriz la relacin entre los
mismos, tomando los valores de 1 si existe la arista y 0 en caso
contrario.

Lista de adyacencias: se asocia a cada nodo del grafo una lista que
contenga todos aquellos nodos que sean adyacentes a l.

7.3 GENERADORES

Crear un grafo vaco: Devuelve un grafo vaco.

op crearGrafo : -> Grafo [ctor] .

Aadir una arista: Dado un grafo, aade una relacin entre dos nodos de
dicho grafo.

op aadirArista : Grafo Nodo Nodo -> [Grafo] [ctor] .

Aadir un nodo: Dado un grafo, incluye un nodo en l, en caso en el que


no exista previamente.

op aadirNodo : Grafo Nodo -> Grafo [ctor] .


7.4 CONSTRUCTORES

Borrar nodo: Devuelve un grafo sin un nodo y las aristas relacionadas


con l. Si dicho nodo no existe se devuelve el grafo inicial.

op borrarNodo : Grafo Nodo -> Grafo .

Borrar arista: Devuelve un grafo sin la arista indicada. En caso de que la


arista no exista devuelve el grafo inicial.

op borrarArista : Grafo Nodo Nodo -> Grafo .


7.5 SELECTORES

Grafo Vacio: Comprueba si un grafo no tiene ningn nodo.

op esVacio : Grafo -> Bool .

Contener Nodo: Comprueba si un nodo pertenece a un grafo.

op contiene : Grafo Nodo -> Bool .

Adyacentes: Comprueba si dos nodos tienen una arista que los


relacione.

op adyacentes : Grafo Nodo Nodo -> Bool .

Para la especificacin de un grafo dirigido tenemos que modificar


algunas de las ecuaciones de las operaciones borrarArista y aadirArista
para que no se considere el caso de aristas bidireccionales.
Y sustituir la operacin adyacentes por:

op predecesor : Grafo Nodo Nodo -> Bool .


op sucesor : Grafo Nodo Nodo -> Bool .
7.6 EJEMPLOS

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
void ingresar_grafo();
void imprimir_grafo();
int w =0, n;
typedef struct nodo{
int dato;struct nodo *sgte;
}nodo;
nodo *vector[20], *actual;
main(){
int opcion;
do{
system("CLS");
printf("\n\t\t\t\t***MENU***\n");
printf("\n\n Diagrama De Pert\n");
printf("\n * Solo trabajar con numeros *\n\n");
printf("\n 1.- Ingresar Nodos");
printf("\n 2.- Imprimir Diagrama:");
printf("\n 3.- SALIR");
printf("\n\n Ingrese una opcion: ");
cin>>opcion;
if(opcion>3 || opcion<0){
printf("\n Opcion NO VALIDA");
printf("\n\n ** PRESIONE CUALQUIER TECLA PARA VOLVER AL
MENU **");
getch();
}
switch(opcion){
case 1:ingresar_grafo();
break;

case 2:
imprimir_grafo();
break;
case 3:opcion=0;
}
}while(opcion!=0);
getch();
}
void ingresar_grafo(){
int i,m,j,valor, x[20],y[20];
printf( "Ingrese n: ");
cin>>n;
for (i=0; i<n; i++)
adyacente:
{
y[i]=i+1;
if(i==n-1){
printf("\n\nNodo final\n");
}
printf("Ingrese numero de vertices adyacentes a %d:",i+1);
cin>>m;
if(i==n-1){
m=0;
printf("No Se Puede Poner Un Nodo Adyacente Al NodoFinal\n\n");
getch();
}
if(m==0 && i!=n-1){
printf("Debe Sealar a Un Nodo\n\n");
getch();
goto adyacente;
}
For (j=0; j<m; j++){
intenta:
printf("Ingrese vertice:");
cin>>valor;
if(valor==i+1){
printf("No Puedes Apuntar Al MismoNodo\n\n");
goto intenta;
}
x[j]=valor;
if(valor==1){
printf("No Puedes Apuntar Al NodoInicio\n\n");
goto intenta;

}
if(valor>n||valor<1){
printf("No Puedes Crear Mas Nodos De Los Preestablecidos\n\n");
goto intenta;
}
for(int h=0 ;h!=j;h++){
if(x[h]==x[j]){
printf("No Puedes Apuntar 2veces A Un Nodo\n\n");
goto intenta;
}
}
if(i>2){
for(int h=i ;h>2;h--){
for(int hh=0;hh!=j;h++){
if(y[h]==x[hh]){
printf("No Puedes Apuntar A Un Nodo Que Y Haya
Sealado A Este\n\n");
goto intenta;
}
}
}
}
actual = (nodo *) malloc(sizeof(nodo));
actual->dato = valor;
actual->sgte = vector[i];vector[i] = actual;
}
}
w=n;
}
void imprimir_grafo(){
int i;
for (i=0; i<w; i++){
printf("\nAdyacente al nodo %d: ",i+1);
actual=vector[i];
while(actual != NULL){
printf("% d", actual->dato);
getch();
actual = actual->sgte;
}
}
}

8 METODOS DE ORDENAMIENTO
Debido a que las estructuras de datos son utilizadas para almacenar
informacin, para poder recuperar esa informacin de manera eficiente
es deseable que aquella est ordenada. Existen varios mtodos para
ordenar
las
diferentes
estructuras
de
datos
bsicas.
En general los mtodos de ordenamiento no son utilizados con
frecuencia, en algunos casos slo una vez. Hay mtodos muy simples de
implementar que son tiles en los casos en dnde el nmero de
elementos a ordenar no es muy grande (ej, menos de 500 elementos).
Por otro lado hay mtodos sofisticados, ms difciles de implementar
pero que son ms eficientes en cuestin de tiempo de ejecucin.
Los mtodos sencillos por lo general requieren de aproximadamente n x
n pasos para ordenar n elementos.
Los mtodos simples son: insertion sort (o por insercin directa)
selection sort, bubble sort, y shellsort, en dnde el ltimo es una
extensn al insertion sort, siendo ms rpido. Los mtodos ms
complejos son el quick-sort, el heap sort, radix y address-calculation
sort. El ordenar un grupo de datos significa mover los datos o sus
referencias para que queden en una secuencia tal que represente un
orden, el cual puede ser numrico, alfabtico o incluso alfanumrico,
ascendente
o
descendente.
Se ha dicho que el ordenamiento puede efectuarse moviendo los
registros con las claves. El mover un registo completo implica un costo,
el cual se incrementa conforme sea mayor el tamao del registro. Es por
ello que es deseable evitar al mximo el movimiento de los registros.
Una alternativa es el crear una tabla de referencias a los registros y
mover las referencias y no los datos. A continuacin se mostrarn los
mtodos de ordenamiento empezando por el ms sencillo y avanzando
hacia los mas sofisticados.
La eficiencia de los algoritmos se mide por el nmero de comparaciones
e intercambios que tienen que hacer, es decir, se toma n como el
nmero de elementos que tiene el arreglo a ordenar y se dice que un
algoritmo realiza O(n2) comparaciones cuando compara n veces los n
elementos, n x n = n2.
8.1 ORDENAMIENTO DE BURBUJA
La Ordenacin
de
burbuja (Bubble
Sort en
ingls)
es
un
sencillo algoritmo de ordenamiento. Funciona revisando cada elemento
de la lista que va a ser ordenada con el siguiente, intercambindolos de
posicin si estn en el orden equivocado. Es necesario revisar varias
veces toda la lista hasta que no se necesiten ms intercambios, lo cual
significa que la lista est ordenada. Este algoritmo obtiene su nombre de

la forma con la que suben por la lista los elementos durante los
intercambios, como si fueran pequeas "burbujas". Tambin es conocido
como el mtodo del intercambio directo. Dado que solo usa
comparaciones para operar elementos, se lo considera un algoritmo de
comparacin, siendo el ms sencillo de implementar.
8.2.1 EJEMPLO C++
#include<stdio.h>
#include<conio.h>
int a[3]={3,2,1};
int i,j,aux,n=3;
void main(){
clrscr();
for(i=0;i<=n;i++){
for(j=0;j<n-1;j++){
if(a[j]>a[j+1]){
aux=a[j];
a[j]=a[j+1];
a[j+1]=aux;
}
}
}
for(i=0;i<3;i++)
{
printf("%d",a);
}
getch();
}
8.3 ORDENAMIENTO SHELL
El ordenamiento Shell (Shell sort en ingls) es un algoritmo de
ordenamiento. El mtodo se denomina Shellen honor de su
inventor Donald Shell. Su implementacin original, requiere O(n2)
comparaciones e intercambios en el peor caso. Un cambio menor
presentado en el libro de V. Pratt produce una implementacin con un
rendimiento de O(n log2 n) en el peor caso. Esto es mejor que las O(n2)
comparaciones requeridas por algoritmos simples pero peor que el
ptimo O(n log n). Aunque es fcil desarrollar un sentido intuitivo de
cmo funciona este algoritmo, es muy difcil analizar su tiempo de
ejecucin. El algoritmo Shell sort mejora el ordenamiento por insercin
comparando elementos separados por un espacio de varias posiciones.
Esto permite que un elemento haga "pasos ms grandes" hacia su
posicin esperada. Los pasos mltiples sobre los datos se hacen con
tamaos de espacio cada vez ms pequeos. El ltimo paso del Shell

sort es un simple ordenamiento por insercin, pero para entonces, ya


est garantizado que los datos del vector estn casi ordenados.
8.3.1 EJEMPLO C++
#include<stdio.h>
#include<conio.h>
int a[5];
int n=5;
void main()
{
int inter=(n/2),i=0,j=0,k=0,aux;
clrscr();
for (i=0; i<5; i++)
{
printf("INSERTA UN VALOR DEL INDICE %d", i);
scanf("%d",& a);
}
while(inter>0){
for(i=inter;i<n;i++)
{
j=i-inter;
while(j>=0) {
k=j+inter;
if(a[j]<=a[k]){
j--;
}
else{
aux=a[j];
a[j]=a[k];
a[k]=aux;
j=j-inter;
}
}
}
inter=inter/2;
}
for(i=0;i<5;i++)
{
printf("%d n",a);
getch();
}
}
8.4 ORDENAMIENTO POR INSERCION

El ordenamiento por insercin (insertion sort en ingls) es una manera


muy natural de ordenar para un ser humano, y puede usarse fcilmente
para ordenar un mazo de cartas numeradas en forma arbitraria.
Requiere O(n) operaciones para ordenar una lista de n elementos.
Inicialmente se tiene un solo elemento, que obviamente es un conjunto
ordenado. Despus, cuando hay k elementos ordenados de menor a
mayor, se toma el elemento k+1 y se compara con todos los elementos
ya ordenados, detenindose cuando se encuentra un elemento menor
(todos los elementos mayores han sido desplazados una posicin a la
derecha) o cuando ya no se encuentran elementos (todos los elementos
fueron desplazados y este es el ms pequeo). En este punto
se inserta el elemento k+1 debiendo desplazarse los dems elementos.
8.3.1 EJEMPLO C++
#include<stdio.h>
#include<conio.h>
int a[4]={4,1,7,2};
int n=4;
int i,j,aux;
void main(){
clrscr();
for(i=1;i<n;i++)
{
j=i;
aux=a;
while(j>0 && aux<a[j-1])
{
a[j]=a[j-1];
j--;
}
a[j]=aux;
}
for(i=0;i<4;i++)
{
printf("%d",a);
}
getch();
}
8.4 ORDENAMIENTO POR SELECCION

El ordenamiento por seleccin (Selection Sort en ingls) es un algoritmo


de ordenamiento que requiere O
de n elementos.
Su funcionamiento es el siguiente:

Y en

operaciones para ordenar una lista

Buscar el mnimo elemento de la lista


Intercambiarlo con el primero
Buscar el mnimo en el resto de la lista
Intercambiarlo con el segundo
general:
Buscar el mnimo elemento entre una posicin i y el final de la lista
Intercambiar el mnimo con el elemento de la posicin i

De esta manera se puede escribir el siguiente pseudocdigo para


ordenar una lista de n elementos indexados desde el 1:
para i=1 hasta n-1
minimo = i;
para j=i+1 hasta n
si lista[j] < lista[minimo] entonces
minimo = j /* (!) */
fin si
fin para
intercambiar(lista[i], lista[minimo])
fin para
8.4.1 EJEMPLO
#include<stdio.h>
#include<conio.h>
int x[4]={1,4,8,6};
int n=4,j=0,i=0;
int temp=0,minimo=0;
void main(){
clrscr();
for(i=0;i<n-1;i++)
{
minimo=i;
for(j=i+1;j<n;j++)
{
if(x[minimo] > x[j])
{
minimo=j;

}
}
temp=x[minimo];
x[minimo]=x;
x=temp;
}
for(i=0;i<n;i++)
{
printf("%d",x);
}
getch();
}

S-ar putea să vă placă și