Arboles
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Arboles

on

  • 4,115 views

 

Statistics

Views

Total Views
4,115
Views on SlideShare
2,653
Embed Views
1,462

Actions

Likes
1
Downloads
111
Comments
1

4 Embeds 1,462

http://pregrado.uniminuto.edu 1424
http://www.slideshare.net 24
http://red1211.blogspot.com 13
http://www.blogger.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Arboles Presentation Transcript

  • 1. Estructuras de Datos y Algoritmos Facultad de Inform´tica a Universidad Polit´cnica de Valencia e Curso 2008/2009 Tema 4: Grafos y ´rboles a FI– UPV: Curso 2008/2009
  • 2. EDA-4 TEMA 4. Grafos y ´rboles a Objetivos • Definiciones, representaci´n y recorrido de ´rboles y grafos. o a Contenidos 1 Grafos: Definiciones b´sicas a 2 Representaci´n de grafos o 3 ´ Arboles: Definiciones b´sicas a 4 ´ Arboles binarios 5 Representaci´n de ´rboles o a 6 Recorridos de ´rboles binarios a 7 Recorrido de grafos 8 Orden topol´gico en grafos ac´ o ıclicos Bibliograf´ ıa • Introduction to Algorithms, de Cormen, Leiserson y Rivest (sec. 5.4, 5.5, 11.4 y 23.1) • Estructuras de datos y algoritmos, de Aho, Hopcroft y Ullman (cap´ ıtulos 3, 6 y 7) FI– UPV: Curso 2008/2009 P´gina 4.1 a
  • 3. EDA-4 ´ 1. GRAFOS: DEFINICIONES BASICAS Grafo dirigido: es un par G = (V, A) donde V es un conjunto finito de elementos llamados v´rtices y A ⊆ V × V es un conjunto de “pares ordenados” de v´rtices llamados e e aristas. Si (u, v) es una arista de G, se dice que el v´rtice v es adyacente a u. e 0 1 2 3 4 5 FI– UPV: Curso 2008/2009 P´gina 4.2 a
  • 4. EDA-4 ´ 1. GRAFOS: DEFINICIONES BASICAS Grafo no dirigido: es un par G = (V, A) donde V es un conjunto finito de v´rtices y e A ⊆ {{u, v} | u, v ∈ V ∧ v = u} es un conjunto de “pares no ordenados” de v´rtices. e Si a = {u, v} es una arista no dirigida, se dice que a une a u y v y que a incide en u y v. Si {u, v} es una arista de G, se dice que el v´rtice v es adyacente a u. La relaci´n es e o sim´trica. e 0 1 2 4 3 FI– UPV: Curso 2008/2009 P´gina 4.3 a
  • 5. EDA-4 ´ 1. GRAFOS: DEFINICIONES BASICAS Grado: para todo v´rtice v, e • grado de entrada es el n´mero de aristas que inciden en v; u • grado de salida es el n´mero de aristas que emergen de v; u • grado es la suma de los grados de entrada y salida de v. El grado de un grafo es el m´ximo grado de sus v´rtices. a e 0 1 2 3 4 5 Ejem.: El grado de entrada del v´rtice 1 es 2; el grado de salida es 1; el grado del v´rtice es 3. El grado del e e grafo es 3. FI– UPV: Curso 2008/2009 P´gina 4.4 a
  • 6. EDA-4 ´ 1. GRAFOS: DEFINICIONES BASICAS Camino desde un v´rtice u ∈ V a un v´rtice v ∈ V : es una secuencia v0, v1, . . . , vk de e e v´rtices de G = (V, A) tal que v0 = u, vk = v, (vi, vi+1) ∈ A, 0 ≤ i < k. e La longitud de un camino v0, v1, . . . , vk es el n´mero de aristas que lo forman. u Camino simple: es un camino v0, v1, . . . , vk en el que todos sus v´rtices son distintos, e excepto quiz´s el primero y el ultimo. a ´ Ciclo: es un camino simple v0, v1, . . . , vk tal que v0 = vk y el camino contiene al menos una arista. Un bucle es un ciclo de longitud 1. 0 1 2 3 4 5 Ejem.: El camino 0, 3, 1, 4 es simple y tiene longitud 3. El camino 0, 1, 4, 3, 1 no es simple. Ejem.: El camino 1, 4, 3, 1 es un ciclo de longitud 3. El ciclo 5, 5 es un bucle. Grafo ac´ ıclico: es un grafo sin ciclos. FI– UPV: Curso 2008/2009 P´gina 4.5 a
  • 7. EDA-4 ´ 1. GRAFOS: DEFINICIONES BASICAS Subgrafo: G = (V , A ) es un subgrafo de G = (V, A) si V ⊆ V ∧ A ⊆ A. Subgrafo inducido: Dado V ⊆ V , el subgrafo de G inducido por V es G = (V , A ) tal que A = {(u, v) ∈ A | u, v ∈ V }. 0 1 2 3 4 5 0 1 0 1 3 4 3 4 Subgrafo Subgrafo inducido por V = {0, 1, 3, 4} FI– UPV: Curso 2008/2009 P´gina 4.6 a
  • 8. EDA-4 ´ 1. GRAFOS: DEFINICIONES BASICAS V´rtice alcanzable desde un v´rtice u: es cualquier v´rtice v para el que existe un e e e camino de u a v. Las componentes conexas en un grafo no dirigido son las clases de equivalencia de v´rtices seg´n la relaci´n “ser alcanzable”. e u o • Un grafo no dirigido es conexo si ∀u, v ∈ V , v es alcanzable desde u. Es decir, si tiene una unica componente conexa. ´ Las componentes fuertemente conexas en un grafo dirigido son las clases de equivalencia de v´rtices seg´n la relaci´n “ser mutuamente alcanzable”. e u o • Un grafo dirigido es fuertemente conexo si ∀u, v ∈ V , v es alcanzable desde u. 0 1 0 1 2 2 4 3 3 4 5 FI– UPV: Curso 2008/2009 P´gina 4.7 a
  • 9. EDA-4 ´ 1. GRAFOS: DEFINICIONES BASICAS Grafo completo: es un grafo G = (V, A) en el que ∀u, v ∈ V , u = v, (u, v) ∈ A. Grafo etiquetado: es un grafo G = (V, A) acompa˜ado de una funci´n f : A → E, n o donde E es un conjunto cuyas componentes se denominan etiquetas. Grafo ponderado: es un grafo etiquetado con n´meros reales (E ≡ R). u 2 Un grafo se considera denso si |A| ≈ |V | . 2 Un grafo se considera disperso si |A| <<< |V | . FI– UPV: Curso 2008/2009 P´gina 4.8 a
  • 10. EDA-4 ´ 2. REPRESENTACION DE GRAFOS: Matriz de adyacencias Un grafo G = (V, A) se representa como G: matriz[V, V ] de booleanos. La componente G[u, v] es 1 si (u, v) ∈ A; sino G[u, v] = 0. Memoria: O(|V |2) → grafos densos |A| ≈ |V |2. Tiempo de acceso: O(1). Lista adyacentes: O(|V |). Lista incidentes: O(|V |). 0 0 1 0 1 0 0 0 1 2 1 0 0 0 0 1 0 2 0 0 0 0 1 1 3 0 1 0 0 0 0 4 0 0 0 1 0 0 3 4 5 5 0 0 0 0 0 1 0 0 1 0 0 1 0 1 1 1 0 1 1 1 2 0 1 0 1 0 2 3 0 1 1 0 1 4 3 4 1 1 0 1 0 FI– UPV: Curso 2008/2009 P´gina 4.9 a
  • 11. EDA-4 1 // Representacion de Grafos: Matriz de adyacencia 2 #include <vector> 3 #include <iostream> 4 using namespace std; 5 class grafoDirigidoBitMat { 6 int numVert; 7 vector<bool> vec; 8 int indice(int u, int v) const { return u*numVert+v; } 9 public: 10 grafoDirigidoBitMat(int nvert) : numVert(nvert),vec(nvert*nvert) {} 11 void insertar_arista(int u, int v) { vec[indice(u,v)] = true; } 12 bool existe_arista(int u, int v) const { return vec[indice(u,v)]; } 13 void imprime(ostream &s) const; 14 }; 15 void grafoDirigidoBitMat::imprime(ostream &s) const { 16 for (int u=0; u < numVert; ++u) { 17 for (int v=0; v < numVert; ++v) 18 s << ((vec[indice(u,v)]) ? ’1’ : ’0’) << ’ ’; 19 s << endl; 20 } 21 } FI– UPV: Curso 2008/2009 P´gina 4.10 a
  • 12. EDA-4 22 ostream& operator << (ostream& s, const grafoDirigidoBitMat &grafo) { 23 grafo.imprime(s); return s; 24 } 25 int main(int argc, char *argv[]) { 26 if (argc != 2) { 27 cerr << "Uso: " << argv[0] << " maxNodosn"; exit(0); 28 } 29 int numVert = atoi(argv[1]); 30 grafoDirigidoBitMat gdmat(numVert); 31 int u,v; 32 while (cin >> u >> v) { // lectura de aristas 33 if (0<=u && u<numVert && 0<=v && v<numVert) 34 gdmat.insertar_arista(u, v); 35 } 36 // volcamos la matriz por salida estandar 37 cout << "nMatriz de adyacencian" << gdmat << endl; 38 return 0; 39 } FI– UPV: Curso 2008/2009 P´gina 4.11 a
  • 13. EDA-4 ´ 2. REPRESENTACION DE GRAFOS: Listas de adyacencia Un grafo G = (V, A) se representa como un vector de listas de v´rtices indexado por v´rtices; e e es decir, G: vector[V ] de V . Cada componente G[v] es una lista de los v´rtices emergentes e y/o incidentes de/a v ∈ V . Memoria: O(|V | + |A|) → grafos dispersos |A| <<< |V |2. Tiempo de acceso: O(grado(G)). Lista adyacentes: O(grado(G)). (Lista incidentes: O(grado(G)) con listas de incidencia.) 0 1 3 NIL 0 1 2 1 4 NIL 2 4 5 NIL 3 1 NIL 4 3 NIL 3 4 5 5 5 NIL 0 1 4 NIL 0 1 1 0 4 3 2 NIL 2 3 1 NIL 2 3 4 2 1 NIL 4 3 4 3 0 1 NIL FI– UPV: Curso 2008/2009 P´gina 4.12 a
  • 14. EDA-4 1 // Representacion de Grafos: Listas de adyacencia 2 #include <iostream> 3 using namespace std; 4 class grafoListaAd { 5 struct arista { 6 int vertice_destino; 7 arista *sig; 8 arista (int v, arista *s) { vertice_destino=v; sig=s; } 9 }; 10 int numVert; 11 arista **vec; 12 public: 13 grafoListaAd(int numVert); 14 bool existe_arista(int u, int v) const; 15 void insertar_arista(int u, int v, bool nueva=false); 16 void imprime(ostream &s) const; 17 }; 18 grafoListaAd::grafoListaAd(int numVert) { 19 this->numVert = numVert; 20 vec = new arista*[numVert]; 21 for (int i=0; i < numVert; i++) vec[i] = 0; 22 } FI– UPV: Curso 2008/2009 P´gina 4.13 a
  • 15. EDA-4 23 bool grafoListaAd::existe_arista(int u, int v) const { 24 for (const arista *r = vec[u]; r != 0; r = r->sig) 25 if (r->vertice_destino == v) return true; 26 return false; 27 } 28 void grafoListaAd::insertar_arista(int u, int v, bool nueva) { 29 if (nueva || !existe_arista(u,v)) 30 vec[u] = new arista(v,vec[u]); 31 } 32 void grafoListaAd::imprime(ostream &s) const { 33 for (int i=0; i < numVert; i++) { 34 s << i << ":"; 35 for (const arista *r = vec[i]; r != 0; r = r->sig) { 36 if (r != vec[i]) s << ","; 37 s << r->vertice_destino; 38 } 39 s << endl; 40 } 41 } 42 ostream& operator << (ostream& s, grafoListaAd &grafo) { 43 grafo.imprime(s); return s; 44 } FI– UPV: Curso 2008/2009 P´gina 4.14 a
  • 16. EDA-4 45 int main(int argc, char *argv[]) { 46 if (argc != 2) { 47 cerr << "Uso: " << argv[0] << " maxNodosn"; exit(0); 48 } 49 int numVert = atoi(argv[1]); 50 grafoListaAd list_ad(numVert); 51 int u,v; 52 while (cin >> u >> v) { // lectura de aristas 53 if (0 <= u && u < numVert && 0 <= v && v < numVert) 54 list_ad.insertar_arista(u, v); 55 } 56 // volcado por salida estandar 57 cout << "nListas de adyacencian" << list_ad << endl; 58 return 0; 59 } FI– UPV: Curso 2008/2009 P´gina 4.15 a
  • 17. EDA-4 Resumen: Representaci´n de grafos o Espacio Matriz de adyacencia Θ(|V |2) Listas de adyacencia Θ(|V | + |A|) Construcci´n del grafo o (u, v) ∈ A Matriz de adyacencia Θ(|V |2) Θ(1) Listas de adyacencia Θ(|V | + |A|) Θ(grado salida(u)) Recorrido sucesores Recorrido predecesores Matriz de adyacencia Θ(|V |) Θ(|V |) Listas de adyacencia Θ(grado salida(u)) Θ(|V | + |A|) Listas de incidencia Θ(|V | + |A|) Θ(grado entrada(u)) FI– UPV: Curso 2008/2009 P´gina 4.16 a
  • 18. EDA-4 Ejercicio: Grafo traspuesto El grafo traspuesto de un grafo dirigido G = (V, A) es un grafo Gt = (V, At) donde (u, v) ∈ At si y s´lo si (v, u) ∈ A. Escribe dos o algoritmos que permitan construir el grafo traspuesto Gt a partir de G: En el primer algoritmo los grafos se representar´n mediante a matrices de adyacencia. En el segundo algoritmo los grafos se representar´n mediante a listas de adyacencia. Calcula el coste computacional de los dos algoritmos. FI– UPV: Curso 2008/2009 P´gina 4.17 a
  • 19. EDA-4 Ejercicio: Grafo traspuesto Se puede modificar el propio grafo: 1 void grafoDirigidoBitMat::trasponer () { // in place 2 for (int u=0; u < vertices; ++u) 3 for (int v=0; v < u; ++v) { 4 bool aux = vec[indice(u,v)]; 5 vec[indice(u,v)] = vec[indice(v,u)]; 6 vec[indice(v,u)] = aux; 7 } 8 } Coste: Recorrer la matriz Θ(|V |2) FI– UPV: Curso 2008/2009 P´gina 4.18 a
  • 20. EDA-4 Ejercicio: Grafo traspuesto O bien devolver otra instancia de la clase: 1 grafoListaAd* grafoListaAd::trasponer() const { // devuelve OTRO grafo 2 grafoListaAd* resul = new grafoListaAd(numVert); 3 for (int u=0; u < numVert; ++u) 4 for (const arista *r = vector[u]; r != 0; r = r->sig) { 5 int v = r->vertice_destino; 6 // le decimos true para no subir el coste innecesariamente: 7 resul->insertar_arista(v,u,true); 8 } 9 return resul; 10 } Coste: Recorrer la matriz Θ(|V | + |A|) FI– UPV: Curso 2008/2009 P´gina 4.19 a
  • 21. EDA-4 Ejercicio: Cuadrado de un grafo El cuadrado de un grafo dirigido G = (V, A) se define como G2 = (V, A ) tal que (u, w) ∈ A si y solo si para alg´n v ∈ V se u cumple que (u, v) ∈ A y (v, w) ∈ A en el grafo G. Escribe dos algoritmos para calcular G2 a partir de G, suponien- do que este ultimo est´ representado como una matriz de ´ a adyacencia y como lista de adyacencia. Calcula el coste temporal de los algoritmos resultantes, justif- ic´ndolo adecuadamente. a FI– UPV: Curso 2008/2009 P´gina 4.20 a
  • 22. EDA-4 Ejercicio: Cuadrado de un grafo Soluci´n con matriz de adyacencia: o 1 grafoDirigidoBitMat* grafoDirigidoBitMat::cuadrado() const { 2 // devuelve otro grafo 3 grafoDirigidoBitMat *resul = new grafoDirigidoBitMat(numVert); 4 for (int u=0; u<numVert; ++u) 5 for (int v=0; v<numVert; ++v) { 6 bool camino=false; 7 for (int w=0; w<numVert && !camino; ++w) 8 camino = camino || (vec[indice(u,w)] && vec[indice(w,v)]); 9 resul->vec[indice(u,v)] = camino; 10 } 11 return resul; 12 } |V | |V | |V | Coste: u=1 v=1 w=1 1 ∈ O(|V |3) FI– UPV: Curso 2008/2009 P´gina 4.21 a
  • 23. EDA-4 Ejercicio: Cuadrado de un grafo Soluci´n con listas de adyacencia: o 1 grafoListaAd *grafoListaAd::cuadrado() const { 2 grafoListaAd *resul = new grafoListaAd(vertices); 3 for (int u=0; u<vertices; ++u) 4 for (const arista* r=vec[u]; r!=0; r=r->sig) 5 for (const arista* s=vec[r->vertice_destino]; s!=0; s=s->sig) 6 resul->insertar_arista(u, s->vertice_destino); 7 return resul; 8 } FI– UPV: Curso 2008/2009 P´gina 4.22 a
  • 24. EDA-4 ´ ´ 3. ARBOLES: DEFINICIONES BASICAS Bosque: es un grafo no dirigido ac´ ıclico. ´ Arbol libre: es un grafo no dirigido ac´ ıclico conexo. ´ Arbol de recubrimiento de un grafo no dirigido G = (V, A): es un ´rbol libre a T = (V , A ) tal que V = V y A ⊆ A. Grafo Bosque Arbol FI– UPV: Curso 2008/2009 P´gina 4.23 a
  • 25. EDA-4 ´ ´ 3. ARBOLES: DEFINICIONES BASICAS Teorema (Propiedades de los ´rboles libres): a Sea G = (V, A) un grafo no dirigido. Los siquientes predicados son equivalentes: 1. G es un ´rbol libre. a 2. Cualquier par de v´rtices est´ conectados por un unico camino. e a ´ 3. G es conexo, pero si se elimina cualquier arista de A, el grafo resultante no es conexo. 4. G es conexo y tiene |V | − 1 aristas. ıclico, y tiene |V | − 1 aristas. 5. G es ac´ 6. G es ac´ ıclico, pero si se a˜ade una arista, se crea un ciclo. n Arbol FI– UPV: Curso 2008/2009 P´gina 4.24 a
  • 26. EDA-4 ´ ´ 3. ARBOLES: DEFINICIONES BASICAS ´ Arbol enraizado Un ´rbol enraizado es un ´rbol libre con un v´rtice (o nodo) distinguido denominado ra´ a a e ız. raíz 7 3 10 4 8 12 11 2 6 5 1 9 Si existe un camino de un nodo x a un nodo y en un ´rbol T , se dice que x es antecesor a de y, y que y es sucesor de x. Si (x, y) es el ultimo arco en el camino desde la ra´ r del ´rbol T hasta el nodo y, ´ ız a entonces x es el padre de y, e y es el hijo de x. La ra´ es el unico nodo en T que no ız ´ tiene padre. Si dos nodos tienen el mismo padre son hermanos. FI– UPV: Curso 2008/2009 P´gina 4.25 a
  • 27. EDA-4 ´ ´ 3. ARBOLES: DEFINICIONES BASICAS ´ Arbol enraizado Un nodo sin hijos lo denominaremos hoja. El resto son nodos internos. El grado de un nodo es el n´mero de hijos que tiene. u Se llama profundidad de un nodo a la longitud del camino desde la ra´ a ese nodo. ız La altura de un ´rbol es la profundidad del nodo m´s profundo. a a 7 profundidad 0 3 10 4 profundidad 1 altura=4 8 12 11 2 profundidad 2 6 5 1 profundidad 3 9 profundidad 4 FI– UPV: Curso 2008/2009 P´gina 4.26 a
  • 28. EDA-4 ´ 4. ARBOLES BINARIOS Un ´rbol binario es un ´rbol en el que el m´ximo n´mero de hijos de cada a a a u nodo es 2 (hijo izquierdo e hijo derecho). 3 profundidad 0 2 7 profundidad 1 4 1 5 altura=3 profundidad 2 6 profundidad 3 Un ´rbol binario se dice que es completo (o lleno) si todas las hojas tienen a la misma profundidad y todos los nodos internos tienen grado 2. Un ´rbol binario es casi-completo si el ´rbol es completo, a excepci´n quiz´s a a o a en el nivel de las hojas, en el cual todas las hojas est´n tan a la izquierda a como sea posible. FI– UPV: Curso 2008/2009 P´gina 4.27 a
  • 29. EDA-4 Propiedades de los ´rboles binarios completos a profundidad num. nodos 0 1=2_0 1 2=2_1 h=3 2 4=2_2 3 8=2_3 ´ Arbol binario completo de altura h = 3, con 8 hojas y 7 nodos internos N´mero de nodos: La ra´ tiene 2 hijos de profundidad 1, cada uno de los cuales tienen 2 u ız hijos de profundidad 2, etc. → Nodos de profundidad i = 2i. h−1 hojas: 2h y nodos internos: 20 + 21 + · · · + 2h−1 = i=0 2i = 2h − 1 h i nodos total: n = i=0 2 = 2h+1 − 1 . . . y la altura n = 2h+1 − 1 → h = log2 n FI– UPV: Curso 2008/2009 P´gina 4.28 a
  • 30. EDA-4 Propiedades de los ´rboles binarios a El m´ximo n´mero de nodos de profundidad i es 2i. a u El m´ximo n´mero de nodos en un ´rbol binario de altura h es a u a 2h+1 − 1. El m´ximo n´mero de nodos internos es 2h − 1. El m´ximo a u a n´mero de hojas es 2h. u La altura m´ınima de un ´rbol binario con n nodos es log2 n . a Para cualquier ´rbol binario no vac´ si n0 es el n´mero de hojas y a ıo, u n2 es el n´mero de nodos de grado 2, entonces n0 = n2 + 1. u ´ Ejercicio. Arboles k-arios. Un ´rbol k-ario es un ´rbol en el que el a a m´ximo n´mero de hijos de cada nodo es k (as´ un ´rbol binario es un a u ı, a ´rbol k-ario con k = 2). ¿Cu´ntas hojas tiene un ´rbol k-ario completo a a a de altura h? ¿Y cu´ntos nodos internos? a FI– UPV: Curso 2008/2009 P´gina 4.29 a
  • 31. EDA-4 ´ ´ 5. REPRESENTACION DE ARBOLES ´ Arboles (n´mero de hijos sin acotar) u • Listas (ordenadas) de hijos. • Hijo m´s a la izquierda-Hermano derecha: variables din´micas a a o vectores. • Con vectores y direcci´n del padre. o • Otros . . . ´ Arboles binarios • Hijo izquierdo e Hijo derecho para cada nodo: variables din´micas o vectores. a ´ • Arbol binario (casi-completo): vector (“heaps”). • Otros . . . FI– UPV: Curso 2008/2009 P´gina 4.30 a
  • 32. EDA-4 ´ ´ 5. REPRESENTACION DE ARBOLES Listas (ordenadas) de hijos raíz 1 2 3 9 NIL 2 NIL 1 3 4 8 NIL 4 5 6 7 NIL 5 NIL 2 3 9 6 NIL 7 NIL 8 NIL 4 8 10 9 10 NIL 10 11 12 NIL 11 NIL 5 6 7 11 12 12 NIL FI– UPV: Curso 2008/2009 P´gina 4.31 a
  • 33. EDA-4 ´ ´ 5. REPRESENTACION DE ARBOLES Hijo m´s a la izquierda-Hermano derecha: variables din´micas o vectores a a clave hizq her_d 2 3 C 10 3 17 D 9 raíz 4 8 A NIL raíz .... 8 NIL B 2 A 9 NIL H NIL 10 13 I NIL B C I A .... 12 NIL G NIL 13 14 J NIL D H J B C I 14 NIL K 16 15 NIL F 12 E F G K L D H J 16 NIL L 7 17 NIL E 15 clave E F G K L .... hizq her_d FI– UPV: Curso 2008/2009 P´gina 4.32 a
  • 34. EDA-4 ´ ´ 5. REPRESENTACION DE ARBOLES Con vectores y direcci´n del padre o 3 3 2 1 9 2 1 9 4 8 10 4 8 10 5 6 7 11 12 5 6 7 11 12 1 2 3 4 5 6 7 8 9 10 11 12 3 3 3 1 4 4 4 1 3 9 10 10 El nodo i es la ra´ del ´rbol si T [i] = i. Cada nodo apunta a su ız a padre: T [i] = padre(i). FI– UPV: Curso 2008/2009 P´gina 4.33 a
  • 35. EDA-4 ´ ´ 5. REPRESENTACION DE ARBOLES ´ Arboles binarios: variables din´micas o vectores a (opcionalmente, puntero al padre) clave hizq hder 2 15 A NIL 3 NIL D NIL raíz raíz 4 8 C 12 .... C 8 3 B 2 9 C 10 B G .... 12 17 G NIL B G D A E 13 14 D A E 15 NIL F NIL F 16 17 NIL E NIL clave F .... hizq hder FI– UPV: Curso 2008/2009 P´gina 4.34 a
  • 36. EDA-4 ´ ´ 5. REPRESENTACION DE ARBOLES ´ Arboles binarios (casi-completos): vector 1 A raiz: T[1] padre[i]=[i/2] 2 3 B C hizquierdo[i]=2i hderecho[i]=2i+1 6 7 4 5 D E F G 8 9 10 11 12 H I J K L 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ... A B C D E F G H I J K L padre hizquierdo raíz hderecho talla=12 FI– UPV: Curso 2008/2009 P´gina 4.35 a
  • 37. EDA-4 ´ 6. RECORRIDOS DE ARBOLES BINARIOS A veces puede interesar un recorrido sistem´tico y eficiente de todos los nodos del ´rbol. a a A B C Recorrido en preorden: ABDEHJICFG Recorrido en inorden: DBHJEIAFGC D E F Recorrido en postorden: DJHIEBGFCA H I G Recorrido en niveles: ABCDEFHIGJ J Coste de todos los algoritmos Θ(n), siendo n el n´mero de nodos del ´rbol → despu´s de la u a e llamada inicial, la funci´n se llama recursivamente exactamente 2 veces para cada nodo del o ´rbol: una vez para su hijo izquierdo y otra para su hijo derecho. a FI– UPV: Curso 2008/2009 P´gina 4.36 a
  • 38. EDA-4 6. Recorridos de ´rboles binarios: PREORDEN a La clave de la ra´ se imprime antes de los valores de sus sub´rboles ız a A B C D E F H I G J 9 void nodo_abb::preorden() { 10 cout << valor << endl; 11 if (h_izq != 0) h_izq->preorden(); 12 if (h_der != 0) h_der->preorden(); 13 } FI– UPV: Curso 2008/2009 P´gina 4.37 a
  • 39. EDA-4 6. Recorridos de ´rboles binarios: INORDEN a La clave de la ra´ se imprime entre los valores de su sub´rbol izquierdo y derecho ız a A B C D E F H I G J 14 void nodo_abb::inorden() { 15 if (h_izq != 0) h_izq->inorden(); 16 cout << valor << endl; 17 if (h_der != 0) h_der->inorden(); 18 } FI– UPV: Curso 2008/2009 P´gina 4.38 a
  • 40. EDA-4 6. Recorridos de ´rboles binarios: POSTORDEN a La clave de la ra´ se imprime despu´s de los valores de sus sub´rboles ız e a A B C D E F H I G J 19 void nodo_abb::postorden() { 20 if (h_izq != 0) h_izq->postorden(); 21 if (h_der != 0) h_der->postorden(); 22 cout << valor << endl; 23 } FI– UPV: Curso 2008/2009 P´gina 4.39 a
  • 41. EDA-4 6. Recorridos de ´rboles binarios: NIVELES a En lugar de una pila (recursi´n) se utiliza una cola. o 24 void abb::por_niveles() { 25 cola *c = new cola(); // una cola de nodo_abb* 26 nodo_abb *n; 27 c->insertar(raiz); 28 while (c->extraer(n)) { 29 if (n != 0) { // se puede poner if (n) { 30 cout << n->valor << endl; 31 c->insertar(n->h_izq); 32 c->insertar(n->h_der); 33 } 34 } 35 delete c; 36 } FI– UPV: Curso 2008/2009 P´gina 4.40 a
  • 42. EDA-4 Ejemplo ´rboles binarios: ´rbol de expresiones a a Utilizaci´n de la estructura AB para representar expresiones aritm´ticas con operadores o e binarios. ra´ operador principal ız: nodos internos: operadores de subexpresiones hojas: operandos (niveles: precedencia relativa de evaluaci´n) o x Recorrido en preorden: × + / a b c − d e notaci´n prefija o polaca o + - Recorrido en inorden: (((a/b) + c) × (d − e)) notaci´n infija o / c d e Recorrido en postorden: a b / c + d e − × notaci´n postfija o polaca inversa o a b FI– UPV: Curso 2008/2009 P´gina 4.41 a
  • 43. EDA-4 7. RECORRIDOS DE GRAFOS M´todo para recorrer de forma sistem´tica y eficiente un grafo. e a Recorrido en profundidad: generalizaci´n del recorrido en preorden de o un ´rbol a Recorrido en amplitud: generalizaci´n del recorrido en niveles de un o ´rbol a En todos los algoritmos de recorrido de grafos supondremos que el grafo est´ implementado con listas de adyacencia. a FI– UPV: Curso 2008/2009 P´gina 4.42 a
  • 44. EDA-4 Recorrido en profundidad de un grafo Dado un grafo G = (V, A) y un v´rtice v ∈ V , la estrategia de recorrido e en profundidad (Depth-First Search (DFS)), explora sistem´ticamente a las aristas de G de manera que primero se visitan los v´rtices adyacentes e a los visitados m´s recientemente. De esta forma, se va profundizando a en el grafo; es decir, alej´ndose progresivamente de v. a Este proceso continua hasta que todos los v´rtices alcanzables desde el e v´rtice de la llamada original han sido descubiertos. e Esta estrategia admite una implementaci´n simple de forma recursiva y o proporciona: Ordenamientos de los v´rtices. e Clasificaci´n de las aristas. o Algunas aplicaciones: Calcular un posible orden topol´gico y comprobar si el grafo es ac´ o ıclico. Encontrar las componentes fuertemente conexas de un grafo. FI– UPV: Curso 2008/2009 P´gina 4.43 a
  • 45. EDA-4 Recorrido en profundidad de un grafo El algoritmo DFS asocia los siguientes datos a cada v´rtice v del grafo: e d[v] ⇒ instante en que el v´rtice v es descubierto e f[v] ⇒ instante en que finaliza la exploraci´n del v´rtice v o e pr[v] ⇒ el v´rtice predecesor de v en el ´rbol generado (´rbol de e a a exploraci´n primero en profundidad, es un subgrafo del grafo original). o El color asociado al v´rtice, que puede ser de 3 tipos: e • WHITE ⇒ cuando nunca ha sido explorado, • GRAY ⇒ mientras est´ siendo explorado, a • BLACK ⇒ cuando ya ha sido explorado. Al principio todos los v´rtices se ponen de color WHITE. Se utiliza un e atributo time como contador para marcar los instantes. FI– UPV: Curso 2008/2009 P´gina 4.44 a
  • 46. EDA-4 Recorrido en profundidad de un grafo 1 void grafo::dfs_visit(int u) {// algoritmo recursivo del DFS 2 color[u] = GRAY; 3 d[u] = ++time; 4 for (arista *r = vec[u]; r != 0; r = r->sig) { 5 int v = r->vertice_destino; 6 if (color[v] == WHITE) { pr[v] = u; 7 dfs_visit(v); } 8 } 9 color[u] = BLACK; 10 f[u] = ++time; 11 } 12 void grafo::dfs() { 13 for (int u=0; u < numVert; ++u) { color[u] = WHITE; 14 pr[u] = -1; } 15 time = 0; 16 for (int u=0; u < numVert; ++u) 17 if (color[u] == WHITE) dfs_visit(u); 18 } Coste Θ(|V | + |A|) FI– UPV: Curso 2008/2009 P´gina 4.45 a
  • 47. EDA-4 Recorrido en profundidad de un grafo: Ejemplo Grafo: 8 vertices aristas: 0 1 0 2 0 3 0 4 1 4 2 3 3 1 3 4 5 6 6 7 5 7 7 5 FI– UPV: Curso 2008/2009 P´gina 4.46 a
  • 48. EDA-4 Recorrido en profundidad de un grafo: Ejemplo dfs_visit(0) (0,4) is a TREE EDGE dfs_visit(4) (0,3) is a TREE EDGE dfs_visit(3) (3,4) is a FORWARD/CROSS EDGE (3,1) is a TREE EDGE dfs_visit(1) (1,4) is a FORWARD/CROSS EDGE (0,2) is a TREE EDGE dfs_visit(2) (2,3) is a FORWARD/CROSS EDGE (0,1) is a FORWARD/CROSS EDGE dfs_visit(5) (5,7) is a TREE EDGE dfs_visit(7) (7,5) is a BACK EDGE (5,6) is a TREE EDGE dfs_visit(6) (6,7) is a FORWARD/CROSS EDGE FI– UPV: Curso 2008/2009 P´gina 4.47 a
  • 49. EDA-4 Recorrido en profundidad de un grafo: Ejemplo v d[v] f[v] pr[v] 0 1 10 -1 1 5 6 3 2 8 9 0 3 4 7 0 4 2 3 0 5 11 16 -1 6 14 15 5 7 12 13 5 FI– UPV: Curso 2008/2009 P´gina 4.48 a
  • 50. EDA-4 Recorrido en profundidad de un grafo Clasificaci´n de las aristas. Una arista (u, v) es de tipo: o TREE o del ´rbol: si el v´rtice v ha sido descubierto a trav´s de a e e dicha arista. Estas aristas definen el bosque del recorrido primero en profundidad, formado por uno o m´s ´rboles. a a BACK o hacia atr´s: si v es un antecesor de u en el ´rbol del recorrido a a primero en profundidad. FORWARD o hacia adelante: si v es un descendiente de u en el ´rbola del recorrido primero en profundidad. CROSS o de cruce: ning´n v´rtice es antecesor del otro. u e El recorrido DFS puede ser utilizado para clasificar las aristas a medida que las va procesando. Cuando desde un v´rtice u se considera la arista e (u, v), se puede observar el color del v´rtice destino v: e WHITE indica que es una arista del ´rbol o TREE. a GRAY indica que es una arista hacia atr´s o BACK. a BLACK indica que es hacia delante o de cruce. Si d[u] < d[v] es hacia delante y si d[u] > d[v] es de cruce. FI– UPV: Curso 2008/2009 P´gina 4.49 a
  • 51. EDA-4 Recorrido en profundidad de un grafo Relaci´n de tipo “par´ntesis”: en la b´squeda primero en profundidad, o e u dados dos v´rtices del grafo u y v, se cumple exactamente una de estas e tres posibilidades: los intervalos [d[u], f [u]] y [d[v], f [v]] son enteramente disjuntos. En este caso, ni u es descendiente de v en el ´rbol DFS ni v descendiente a de u. el intervalo [d[u], f [u]] est´ contenido enteramente dentro del inter- a valor [d[v], f [v]] y u es descendiente de v en el ´rbol DFS. a el intervalo [d[v], f [v]] est´ contenido enteramente dentro del intervalor a [d[u], f [u]] y v es descendiente de u en el ´rbol DFS. a La relaci´n de estos intervalos tambi´n sirve para clasificar las aristas, o e as´ la arista (u, v) es: ı del ´rbol si d[u] < d[v] < f [v] < f [u] a hacia atr´s si d[v] < d[u] < f [u] < f [v] a de cruce si d[v] < f [v] < d[u] < f [u] FI– UPV: Curso 2008/2009 P´gina 4.50 a
  • 52. EDA-4 Orden topol´gico o Un orden topol´gico de un grafo dirigido ac´ o ıclico G = (V, A) es una ordenaci´n de los v´rtices de forma que si (u, v) ∈ A, entonces u aparece o e antes que v. (La soluci´n no es unica.) Ejem.: prerrequisitos de los o ´ estudios. ¡No es posible la ordenaci´n topol´gica cuando existen ciclos! o o a b d a e b c c d e a b d e c Orden no unico. ´ Ordenaci´n de v´rtices en eje horizontal con las aristas de izquierda a derecha. o e FI– UPV: Curso 2008/2009 P´gina 4.51 a
  • 53. EDA-4 Orden topol´gico o Dado un grafo G = (V, A), el DFS puede usarse para determinar si es ac´ ıclico y, en ese caso, obtener un orden topol´gico. o El grafo es ac´ıclico si no tiene ninguna arista hacia atr´s. a El orden en que finaliza la exploraci´n de los v´rtices (valor guardado o e en f [v]) es un orden topol´gico invertido. o 1 void grafo::dfs_visit(int u) { 2 color[u] = GRAY; 3 d[u] = ++time; 4 for (arista *r = vec[u]; r != 0; r = r->sig) { 5 int v = r->vertice_destino; 6 if (color[v] == WHITE) { pr[v] = u; 7 dfs_visit(v); 8 } else if (color[v] == GRAY) es_aciclico = false; 9 } // es_aciclico esta a true antes de empezar DFS 10 color[u] = BLACK; 11 f[u] = time; 12 topologic_sort.push_front(u); // insertar al ppio 13 } FI– UPV: Curso 2008/2009 P´gina 4.52 a
  • 54. EDA-4 Recorrido en profundidad de un grafo: Ejemplo 2 dfs_visit(0) Grafo: (0,2) is a TREE EDGE dfs_visit(2) 11 (2,4) is a TREE EDGE 0 1 dfs_visit(4) (4,7) is a TREE EDGE 0 2 dfs_visit(7) 1 3 (4,6) is a TREE EDGE dfs_visit(6) 2 4 (0,1) is a TREE EDGE 3 2 dfs_visit(1) (1,9) is a TREE EDGE 3 4 dfs_visit(9) 3 5 (9,10) is a TREE EDGE 5 7 dfs_visit(10) (1,8) is a TREE EDGE 4 6 dfs_visit(8) 4 7 (8,10) is a FORWARD/CROSS EDGE (1,3) is a TREE EDGE 1 8 dfs_visit(3) 1 9 (3,5) is a TREE EDGE dfs_visit(5) 8 10 (5,7) is a FORWARD/CROSS EDGE 9 10 (3,4) is a FORWARD/CROSS EDGE (3,2) is a FORWARD/CROSS EDGE FI– UPV: Curso 2008/2009 P´gina 4.53 a
  • 55. EDA-4 Recorrido en profundidad de un grafo: Ejemplo 2 v d[v] f[v] pr[v] 0 1 22 -1 1 10 21 0 2 2 9 0 3 17 20 1 4 3 8 2 5 18 19 3 6 6 7 4 7 4 5 4 8 15 16 1 9 11 14 1 10 12 13 9 Un posible orden topologico: 0 1 3 5 8 9 10 2 4 6 7 FI– UPV: Curso 2008/2009 P´gina 4.54 a
  • 56. EDA-4 Otro algoritmo para el orden topol´gico, sin DFS o 1 void grafo::orden_topologico_sin_dfs() { // test aciclicidad 2 int u,v; arista *r; 3 for (v=0; v < numVert; ++v) grado_entrada[v] = 0; 4 for (v=0; v < numVert; ++v) 5 for (r = vec[v]; r != 0; r = r->sig) 6 grado_entrada[r->vertice_destino]++; 7 col->vaciar(); 8 for (v=0; v < numVert; v++) 9 if (grado_entrada[v] == 0) col->insertar(v); 10 for (n = 0; col->extraer(u); n++) { 11 topologic_sort.push_back(u); // insertar al final 12 for (arista *r = vec[u]; r != 0; r = r->sig) { 13 grado_entrada[r->vertice_destino]--; 14 if (grado_entrada[r->vertice_destino] == 0) 15 col->insertar(r->vertice_destino); 16 } 17 } 18 es_aciclico = (n == numVert); 19 } FI– UPV: Curso 2008/2009 P´gina 4.55 a
  • 57. EDA-4 Recorrido en amplitud de un grafo Dado un grafo G = (V, A) y un v´rtice s ∈ V , la estrategia de e recorrido en amplitud o en anchura (Breadth-First Search (BFS)), explora sistem´ticamente las aristas de G de manera que primero se a visitan los v´rtices m´s cercanos a v. e a Algunos algoritmos importantes de grafos tienen una estructura similar al BFS. Por ejemplo, el algoritmo de Prim para encontrar el ´rbol de a expansi´n de m´ o ınimo coste, o el algoritmo de Dijkstra para encontrar los caminos m´s cortos desde un v´rtice dado. a e El algoritmo BFS explora todos los v´rtices a distancia k del v´rtice e e origen s antes de empezar a explorar los v´rtices a distancia k + 1. e Al igual que DFS, se utiliza un vector de tipo “color” para marcar los v´rtices del grafo como no visitados (WHITE), visit´ndose (GRAY) o e a ya visitados (BLACK). Tambi´n se genera un vector de predecesores para obtener un ´rbol. e a FI– UPV: Curso 2008/2009 P´gina 4.56 a
  • 58. EDA-4 Recorrido en amplitud de un grafo 1 void grafo::bfs(int vertice) { 2 cola.clear(); 3 for (int u=0; u < numVert; ++u) { 4 color[u]=WHITE; pr[u]=-1; d[u]=numVert+1; 5 // numVert+1> cualquier distancia en el grafo 6 } 7 cola.push_back(vertice); 8 d[vertice] = 0; 9 while (!cola.empty()) { 10 int u = cola.front(); cola.pop_front(); // extraer 11 for (arista *r = vec[u]; r != 0; r = r->sig) { 12 int v = r->vertice_destino; 13 if (color[v] == WHITE) { 14 color[v]=GRAY; d[v]=d[u]+1; pr[v]=u; 15 cola.push_back(v); 16 } 17 } 18 color[u] = BLACK; 19 } 20 } FI– UPV: Curso 2008/2009 P´gina 4.57 a
  • 59. EDA-4 Recorrido en amplitud de un grafo: Ejemplo Grafo: 11 0 1 0 2 1 3 2 4 3 2 3 4 3 5 5 7 4 6 4 7 1 8 1 9 8 10 9 10 FI– UPV: Curso 2008/2009 P´gina 4.58 a
  • 60. EDA-4 Recorrido en amplitud de un grafo: Ejemplo v d[v] pr[v] Cola: salen< 0 <entran 0 0 -1 Cola: salen< 2 1 <entran 1 1 0 Cola: salen< 1 4 <entran 2 1 0 Cola: salen< 4 9 8 3 <entran 3 2 1 Cola: salen< 9 8 3 7 6 <entran 4 2 2 Cola: salen< 8 3 7 6 10 <entran 5 3 3 Cola: salen< 3 7 6 10 <entran 6 3 4 Cola: salen< 7 6 10 5 <entran 7 3 4 Cola: salen< 6 10 5 <entran 8 2 1 Cola: salen< 10 5 <entran 9 2 1 Cola: salen< 5 <entran 10 3 9 FI– UPV: Curso 2008/2009 P´gina 4.59 a