ARBOLES
Introduccion
Las estructuras de datos grafos son llamadas estructuras de ramificacion,ya que un elemento, en comparacion con las estructuras lineales,puede tener mas de un siguiente elemento.
En esta tutorial vamos a hablar de un caso especial de grafos, denominado ARBOL o TREE.
[+] Definicion de Arbol
Un arbol es un conjunto finito de 0 o mas nodos v1,v2,...,vn tales que:
1- existe un nodo el cual se distingue de los demas, al mismo lo vamos llamar raiz
2- los demas elementos del conjuntos quedan particionados en m>=0 conjuntos disjuntos T1,T2,...,TN los cuales son arboles.
los elementos T1,T2,...,TN son llamados subarboles. Vemos aqui la naturaleza recursiva de la estructura arbol, puesto que definimos arbol en termino de arboles.
-El grado interior del nodo raiz es nulo, esto quiere decir que no
existen ramificaciones de entrada hacia el.
-Los nodos que tienen grado exterior=0 se dicen que son nodos hojas de un arbol.
-Se dice que un arbol esta en niveles, los cuales estan determinados
por la longuitud de la trayectoria desde la raiz hacia dicho nodo.
-El peso de un arbol esta determinado por el numero de nodos hojas
-La altura de un arbol es 1 mas el el mayor nivel de nodos
-Un conjunto de arboles enraizados se dice que forman un bosque.
[+] Arboles Binarios
Un arbol binario es un caso especial de arboles generales.
Es un conjunto finito de 0 nodos, o mas que tienen un subconjunto
disjunto de 2 nodos, uno denominado subarbol derecho y otro
subarbol izquierdo.
[+] convertir Arboles Generales a Arboles binarios
Esto se realiza obviamente porque es mas facil
representar arboles binarios que arboles generales, debido
a que la cantidad de apuntadores predecibles son 2:
subarbol derecho y subarbol izquierdo.
El algoritmo que permite realizar esta operacion de
conversion, o transformacion es el siguiente:
1- insertar aristas uniendo los nodos hermanos y eliminar
aquellas aristas que unen a los nodos hijos con su padre,
excepto el de mas a la izquierda.
2- girar este arbol aproximadamente unos 45º para distinguir
los subarboles derecho e izquierdo.
[+] Representacion de un arbol
Un arbol se lo puede representar mediante la implementacion dinamica de memoria, esto es utilizando listas encadenadas o ligadas.
cada nodo va a tener la siguiente configuacion:
|PI|INFO|PD|
donde PI: apunta hacia el nodo izquierdo (subarbol izquierdo) de ese nodo
INFO: es el campo donde se almacena la informacion
PD: apunta hacia el nodo derecho (subarbol derecho)de ese nodo.
[+] Arboles en JAVA...
Vamos a realizar una pequeña aplicacion en java que nos permita
entender el concepto de arbol, el programa realizara inserciones, eliminaciones e imprimira los elementos del arbol generado.
Clases:
Nodo
Arbol
ArbolAplicacion
Principal
#######################################################
Clase NODO #######################################################
public class Nodo {
private Nodo pd;
private Object dato;
private Nodo pi;
public Nodo(Object dato){
this.dato=dato;
pd=null;
pi=null;
}
public Object getDato() {return dato;}
public void setDato(Object dato) {this.dato = dato;}
public Nodo getPd() {return pd;}
public void setPd(Nodo pd) {this.pd = pd;}
public Nodo getPi() {return pi;}
public void setPi(Nodo pi) {this.pi = pi;}
}
#######################################################
#######################################################
CLASE ARBOL #######################################################
public class Arbol {
private Nodo Raiz;
public Arbol(){ Raiz=null;}
// insertar(Raiz, Raiz, x)
public boolean arbolVacio(){return Raiz == null;}
public void insertar(Nodo ant, Nodo p, Nodo x){
if (p != null){
if (Integer.parseInt(x.getDato().toString()) > Integer.parseInt(p.getDato().toString())) {
insertar(p, p.getPd(), x);
}else{
insertar(p, p.getPi(), x);
}
}else{
if (arbolVacio()){
Raiz = x;
}else{
if (Integer.parseInt(x.getDato().toString()) > Integer.parseInt(ant.getDato().toString())) {
ant.setPd(x);
}else {
ant.setPi(x);
}
}
}
}
public void imprimir(Nodo p){
if(p != null){
imprimir(p.getPi());
System.out.print(p.getDato()+"; ");
imprimir(p.getPd());
}
}
public Nodo getRaiz() {
return Raiz;
}
public void setRaiz(Nodo raiz) {
Raiz = raiz;
}
public void eliminar(Nodo ant, Nodo p){
if(esNodoHoja(p)){
eliminarNodoHoja(ant, p);
}else{
if (esNodoCon2SubArboles(p)){
eliminarNodoCon2SubArboles(ant, p);
}else{
eliminarNodoCon1SubArnol(ant, p);
}
}
}
public void eliminarNodoHoja(Nodo ant, Nodo p){
if (Raiz != p){
if(ant.getPd() == p){
ant.setPd(null);
}else{
ant.setPi(null);
}
}else{
Raiz = null;
}
}
public void eliminarNodoCon1SubArnol(Nodo ant, Nodo p){
if (Raiz == p){
if(p.getPd() != null){
Raiz = Raiz.getPd();
}else{
Raiz = Raiz.getPi();
}
}else{
if ( ant.getPd() == p){
if(p.getPd() != null){
ant.setPd(p.getPd());
}else{
ant.setPd(p.getPi());
}
}else{
if(p.getPd() != null){
ant.setPi(p.getPd());
}else{
ant.setPi(p.getPi());
}
}
}
}
public boolean esNodoHoja(Nodo p){return (p.getPi() == null && p.getPd() == null);}
public boolean esNodoCon2SubArboles(Nodo p){return (p.getPi() != null && p.getPd() != null);}
#######################################################
#######################################################
CLASEARBOLAPLICACION
#######################################################
import java.io.*;
import java.io.InputStreamReader;
public class ArbolAplicacion {
Arbol miArbol;
BufferedReader entrada;
public ArbolAplicacion(){
miArbol = new Arbol();
entrada = new BufferedReader(new InputStreamReader(System.in));
}
public void generar()throws Exception{
// Nodo p = miArbol.getRaiz();
char op='s';
while(op !='n' && op!='N'){
System.out.println(" Ingrese elemento");
Object elem = entrada.readLine();
Nodo x = new Nodo(elem);
miArbol.insertar(miArbol.getRaiz(), miArbol.getRaiz(), x);
System.out.println(" Continuar enter/ n");
String opcion=entrada.readLine();
opcion=opcion.equals("")?"a":opcion;
op = opcion.charAt(0);
}
}
public void eliminarNodo()throws Exception{
// Nodo p = miArbol.getRaiz();
char op='s';
while(op !='n' && op!='N'){
System.out.println(" Ingrese elemento");
Object elem = entrada.readLine();
Nodo x=new Nodo(elem);
// Buscar
buscarEnElArbol(miArbol.getRaiz(), miArbol.getRaiz(), x);
System.out.println(" Continuar enter/ n");
String opcion=entrada.readLine();
opcion=opcion.equals("")?"a":opcion;
op = opcion.charAt(0);
}
}
public void buscarEnElArbol(Nodo ant, Nodo p, Nodo x){
if(p!=null){
if(Integer.parseInt(x.getDato().toString())==Integer.parseInt(p.getDato().toString())){
miArbol.eliminar(ant, p);
}else{
if(Integer.parseInt(x.getDato().toString())>Integer.parseInt(p.getDato().toString())){
buscarEnElArbol(p,p.getPd(),x);
}else{
buscarEnElArbol(p,p.getPi(),x);
}
}
}
}
public void imprimirArbol(){
System.out.println("=====================");
System.out.println("Elementos del arbol");
miArbol.imprimir(miArbol.getRaiz()) ;
System.out.println("");
System.out.println("=====================");}
public void mostrarOpciones(){
System.out.println("=================");
System.out.println(" Opciones de Arbol");
System.out.println("1- Generar");
System.out.println("2- Eliminar");
System.out.println("3- Imprimir");
System.out.println("Ingrese su opciones:"); }
public void menu()throws Exception{
int op = 9;
do{
switch (op) {
case 1: generar(); break;
case 2: eliminarNodo(); break;
case 3: imprimirArbol(); break;}
mostrarOpciones();
String opc = entrada.readLine();
opc = opc.equals("")?"9":opc;
op=Integer.parseInt(opc);
}while(op!=0);
}
public static void main(String[] args)throws Exception {
ArbolAplicacion mi=new ArbolAplicacion();
mi.menu();
}
}
#######################################################
#######################################################
CLASE PRINCIPAL
#######################################################
public class Principal {
public static void main(String[] args) throws Exception {
ArbolAplicacion miA=new ArbolAplicacion();
miA.menu();
}}
Estruc.Arboles
18:16 |
Read User's Comments0
grafos.estrucDato
18:15 |
LOS PUENTES DE Koenigsberg
Leonardo Euler estudió el asunto, representó las distintas zonas A, B, C y D por medio de puntos, mientras que los puentes estaban representados por líneas que unían estos puntos.
A la figura la llamó grafo, a los puntos los llamó vértices y a las líneas las denominó aristas.
Euler estudió si una figura lineal se podía dibujar con un solo trazo, y sin pasar dos veces por el mismo sitio. Llegó a la siguiente conclusión:
1. Es imposible si hay más de dos vértices impares.
2. Es posible cuando:
a) Todos los vértices son pares y el punto de partida puede ser cualquiera.
b) Cuando no hay más de dos vértices impares y en este caso el comienzo del recorrido comienza en uno de ellos y termina en el otro.
Euler demostró que hay un camino que comienza en un vértice, pasa por todas las aristas una sola vez y vuelve al punto de partida sí y sólo sí el grado de cada vértice es par (circuito Euleriano).
GRAFOS
“Un grafo G es un par (V(G), A(G)), donde V(G) es un conjunto no vacío de elementos llamados vértices, y A(G) es una familia finita de pares no ordenados de elementos de V(G) llamados aristas”.
-Se permite la posibilidad de aristas múltiples en el grafo, más de una arista con el mismo par de vértices como origen y destino.
-Se permite la existencia de aristas bucles, con inicio y destino el mismo vértice”
DEFINICIONES FUNDAMENTALES
Bucle: Toda arista de la forma (v, v)
Vértices adyacentes: se dice que 2 vértices son adyacentes si están unidos por una arista.
Aristas adyacentes :se dice que 2 aristas son adyacentes cuando tiene un vértice en común.
Se dice que un vértice es aislado si no es adyacente a ningún otro vértice.
Se dice que un grafo es simple si no tiene bucles ó aristas múltiples.
Tipos de Grafos
a) Grafo Regular: Si G=(V,A), de grado “n”, si todos sus vértices tiene grado “n”.
b) Grafo dirigido o dígrafo: Es un par G=(V,A), consistente en un conjunto finito no vacío V, cuyos miembros se llaman vértices y una familia finita A de pares ordenados de vértices a cuyos extremos llamaremos arista ó arcos.
Las aristas de los dígrafos tienen sentido
Representación de Grafos
- Matriz de adyacencia
- Matriz de incidencia
- Listas
“Sea un grafo G=(V,A), con n- vértices {v1, v2, v3, ……,vn}, su matriz de adyacencia es la matriz de orden nxn, M(G)=(aij), donde aij es el número de aristas que unen los vértices vi y vj”
Matriz de incidencia
“Es determinable cuando no existen vértices con aristas del tipo (v,v)”
Las matrices de incidencia sólo contienen ceros y unos
Matriz de adyacencia-Dígrafos
“Dado un dígrafo D=(V,E), con n-vértices {v1, v2, v3, ……,vn}, su matriz de adyacencia es la matriz de orden nxn, M(D )=(aij), donde aij es el número de arcos que tienen a vi de inicio y a vj de fin”
Matriz de incidencia-Dígrafos
“Cada fila representa a cada uno de los nodos del grafo, y las columnas las aristas, en la casilla M(i,j), aparecerá un 1 cuando el nodo de la fila i es inicial, y un -1 cuando el nodo i es final”
Exploración e Grafos: Recorridos
- Recorrido en profundidad.
- Recorrido en anchura.
Recorrido en profundidad
Profundidad : 1-2-3-4
Recorrido en anchura o niveles
Recorrido en anchura o niveles
Anchura : 1-2-4-3
Estructura de datos I
17:59 |
| ESTRUCTURAS DINAMICAS Dinámicas Lineales.- -> Listas Enlazadas.- Simples, Dobles, Circulares -> Pilas -> Cola -> Biloca Dinámicas No Lineales.- -> Arboles.-Binarios, Binarios De Búsqueda -> Grafos La lista enlazada es una estructura de datos dinámicas formada por un conjunto de nodos, conectados atreves de uno enlace (sig.); Queda definida básicamente al x Nombre, enlaza al 1 nodo (elemento) y 1 enlace al último Nodo (elem). Lista enlazada puede ser movida sobre la memoria y también ser rápidamente serializada para almacenarla en un disco o transferirla sobre una red. Una lista enlazada es una serie de nodos, conectados entre sí a través de una referencia, en donde se almacena la información de los elementos de la lista. Especialmente para una lista pequeña, los arrays indexados pueden ocupar mucho menos espacio que un conjunto de punteros. La localidad de referencia puede ser mejorada guardando los nodos juntos en memoria y siendo reordenados periódicamente. Public Class Nodo { Object Dato; Nodo Enlace; }
This (obj; null); // SOLO }
Public nodo (Object obj, Nodo sig){ Dato=obj; Enlace=sig; // ENLAZADO }
Public getDato () {return Dato ;} }//fin
….. Null Clase nodo { Object dato;
Nodo (Object 0) { Dato = 0; Sig = null; } //------------------------------------------------------------- Nodo (Object 0, Nodo n) { Dato = 0; Sig = n; } //Lista no vacia Object getDato () { Return Dato; } Nodo getEnlace () {-} OPERACIONES. -INSERTAR -ELIMINAR -BUSCAR -ORDENAR -Operaciones -> Constructor -> Lista Vacia Constructor Public Lista (String n) { Nombre = n; Pri = ult = null; } Public boolean ListaVacia () { Return ( pri == null); } INSERCIONES.- Frente Posterior Pos_n Insertar al frente.- 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. Public void InsertarFrente (Object obj){ If (ListaVacia ()) Prim = ult = null (obj); Else Prim=new Nodo (obj, pri); } Insertar Posterior.- 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 Public void InsPosterior (Object obj) { If (listaVacia ()) Prim=ult=new nodo (obj); Else Ult=ult.sig=new nodo (obj); } -CONTAR NODO DE UNA LISTA Public int contnodos () { Nodo Actual=Prim; int cont=0; While (Actual != null) { Cont++; Actual=Actual.sig;//avanza } Return cont; } } Insertar Pos_n Public void insPos_n (object obj, int pos) { If (ListaVacia ()) InsertaFrente (); Else { If (pos==1){insertaFrente();} If (pos==ContElem ()){insertaPosterior; Else { Nodo Actual=Prim; For (int i = 0; i <= pos_n; i++){ Actual=Actual.sig; } Nodo Nuevo=new Nodo (obj, Actual.sig) Actual sig=nuevo; } } } Public class lista simple { Private nodo prim; Private nodo ult; Private string nombre; } Public lista Simple (){ Prim=ult=null; Nombre=””; } Public lista simple (string n){ Prim = ult = null; Nombre = n; } Public Boolean ListaVacia () { Return prim==null; } Public void InsFrente (Object obj) {} Public void Insposterior (Object obj) {} Public void insposicion (Object obj, int pos) {} ELIMINACIONES.- Eliminar al Frente Public object DelFrente () { If (Listavacia ()) trows excepcion Object datoARemover = prim.dato; If (prim.equals cult) Prim=ult=null; Else { Nodo Actual = prim; Prim = prim.sig; Actual.sig=null; } Return datoARemover; } Eliminar Posterior 1 If (listaVacia ()) Object DatoARemover = ult.dato; 2 If (prim.equals (null)) Prim=ult=null; 3 Else { Nodo Actual=pri; While (Actual.sig != ult) Actual=Actual.sig; } Eliminar Pos_n Public void ElemPos_n (Object, int Pos) If (listaVacia ()) {ElimFrente () ;} Else { If (pos==1) {ElimFrente () ;} If (pos==cantElem ()) ;{ elemPost () ;} Else { Nodo=Actual=prim; For (int i=1; i<=Pos_n; i++) { Actual=Actual.sig; datoARemover=Pos.Dato; } Return DatoaRemover; } //PARA ELIMINAR ENTRE MEDIO Y ENLAZAR AL SIGUIENTE Public object DelPos (int Pos) { If (ListaVacia) If (Pos == 1) DelFrente () { If (Pos == numElemen) DelPosterior (); Else { Object DatoARemoer If (prim.equals (ult)) { Prim = ult = null; Return DatoARemover; } Else { Nodo actual = prim; For (int i = 1; i <= pos; i++) { Actual = actual.sig; DatoARemover = (actual.sig).Dato (aBorrar.Dato) Actual.sig = (actual.sig).sig; (aBorrar.sig); aBorrar.sig = null; Return DatoARemover; } } } } } //MODIFICACIONES AL FRENTE Algoritmo completo Public void update frente (object obj new) If (listaVacia ()) Else Prim.Dato = obj new; //MODIFICACIONES POSTERIOR Algoritmo completo Public void update post (object obj) If (listaVacia ()) Else ult.Dato = obj; //MODIFICA LA POSICION a) Lista Vacia Lista X Null Algoritmo System(error) b) No Vacia pos new elemento <>, y <> new element Algoritmo Si pos = new elem => update pos (obj new)< Actual.dato = object new; Algoritmo completo Public void update pos (object obj new, int pos) { If (listaVacia ()) //ERROR If (pos == 1) updateFrente (obj new); If (pos == numElemen) update post (object new); Else { nodo.actual = prim; For (int i = 1; I <= pos; i++) Actual = actual.sig; actual.dato = obj new; } } //MOSTRAR LISTA Public void mostrarLista () { Nodo. Actual = prim; While (actual != null) Joptionpane (actual.dato) Actual = actual.sig; } //PILA (STACK) Una Pila es un lugar donde se almacenan datos, pero una Pila tiene una filosofía de entrada y salida de datos ultimo en entrar, primero en salir. Esta estructura de datos tiene muchas aplicaciones debido a su simplicidad. Las pilas suelen emplearse en los siguientes contextos: Evaluación de expresiones en notación postfija (notación polaca inversa). Reconocedores sintácticos de lenguajes independientes del contexto Implementación de recursividad. Pila (insPosterior, delPosterior) Class pila extends listaSimple{ Public pila() {super (“Pila”);{ Public void push ( object obj) { Inserter posterior ( obj); } Public object pop () { //eliminar Return del posterior (); } Public void mostrarPila (){ mostrarLista (); }//ultimo en entrar y primero en salir } Class prueba{ Main () { Pila p=new pila (“Pila X”); p.push (“Ana”); p.push (“Juan”); p.pop (); // Juan p.pop (); //Ana } } Class cola extends ListaSimple{ Public cola () {super (“cola”) ;{ // insertar Insertar posterior (obj); } Public object decolar () {// eliminar Return del frente (); } Public void mostrar cola (){ mostrarLista (); }// Primero en entrar y primero en salir } Class prueba { Public static void main(…){ Cola c = new cola(“X”); c. encolar (“Juana”); c. encolar (“Ana”); c. encolar (“Pepe”); c. encolar (); c. encolar (); ListaSimple Lista X = new ListaSimple (“ ”); // Llenado de la lista se asume Pila Lista1 = new Pila (“P”); Cola Lista2 = new Cola (“C”); While (object lista X.ListaVacia ()) { Object obj = ListaX.Del frente (); If (obj.estado == “Bueno”) Lista1.push (obj); //insertar pila Else Lista2.encolar (obj); // insertar cola } En el main principal Int cod = in….(jop…(“cod”)) ; String =b jop…(“Nombre”) listaEnlazada L1 = new ListaEnlazada(“Lista X”) L1.insfrente (new Estudiante (cod, nom))//insfrente un objeto Estudiante obj: Obj = (Estudiante) L1.deleteFrente(); //delete frente retorna un objecto System…(obj.getcod+obj.getnombre); *Se decea registrar los datos de 10 vendedores Nombre, apellido, dirección, fono Main principal Lista enlazada L1 = new.ListaEnlazada (“Lista X”); For ( int i = 1; i <= 0; i++){ String nombre = joption.pane(“Nombre”); String apellido = joption.pane(“Apellido”); String direccion = joption.pane(“Direccion”); String telefono = joption.pane(“Telefono”); L1.insposterior(new vendedor (nombre, apellido, direccion, telefono)) } } Vendedor obj; For(int i = 1; i <= 10; i++){ Obj = (vendedor) L1.deleteposterior(); System.out.println(obj.getnombre()+obj.getapellido()+obj.getdireccion()+ LISTA DOBLE CIRCULAR
Ant ant ant Realizar el siguiente recorrido 1: 1-2-3-2 = (actual.sig.sig).ant 2: 2-3-4-1-4 = (((actual.sig).sig).sig).ant 3: 1-2-1-4 = (((actual.sig).ant).sig) Recorrido optimo 4: 1-4 = actual.ant 5: 3-1 = (actual.ant).ant 6: 2-4 = (actual.sig ).sig Lista Circular Una lista circular es aquella en donde la referencia siguiente del último nodo en vez de ser null apunta al primer nodo de la lista. El concepto se aplica tanto a listas de enlace simple como doblemente enlazadas. Class nodoDoble{ Object Dato ; Nodo sig; Nodo ant; Public nodoDato () { } } Class listaDobleCircular{ String Nombre; Nodo ultimo; Nodo actual; // OPCIONAL } INSERCIONES InsUltimo Nuevo.sig = ultimo.sig; Nuevo.ant = ultimo; Ultimo.sig.ant = Nuevo; Ultimo.sig = Nuevo; Ultimo = Nuevo; InsPos_n Nuevo.sig = actual.sig; Nuevo.ant = actual; Actual.sig.ant = Nuevo; Actual.sig = Nuevo; Eliminaciones DeleteUltimo 1 actual.sig = ultimo.sig; 2 actual.sig.ant = actual; 3 ultimo = null; Ultimo.ant = ultimo.sig = null; DeletePrimero 1 actual sig.ant = ultimo; 2 ultimo.sig = actual.sig; 3 actual.sig = actual.ant =null; Del Pos_n Aux.sig = actual.sig; Actual.sig.ant = aux; Actual.sig = actual.ant = null; |
Suscribirse a:
Entradas (Atom)





