TEÓRICO PRÁCTICAS 1.1 Mezcla Equilibrada-Múltiple Mediante este método se intenta reducir el número de iteraciones a costa de aumentar el número de ficheros auxiliares. Se van a utilizar “m” ficheros auxiliares, de los que “m/2” serán de entrada y “m/2” de salida (nº de ficheros de entrada = nº de ficheros de salida). Siempre nos dirán cuantos tenemos de entrada y cuantos de salida, o bien el número de ficheros que podemos utilizar (de los cuales la mitad serán de entrada y la otra mitad de salida). Veamos un ejemplo. Nos dicen que usemos 6 ficheros, 3 de entrada y 3 de salida. Nos dan el siguiente fichero para aplicar el método de mezcla equilibrada. 238 – 832 – 453 – 68 – 18 – 3 – 13 – 98 – 31 – 1 – 84 – 7 – 374 - 212 – 631 – 89 – 16 – 198 – 37 – 81 – 217 – 2 – 65 – 87 – 321 – 698 – 571 – 354 – 987 – 863 – 539 – 254 – 368 – 693 Separamos el fichero origen en tres ficheros de entrada aprovechando la ordenación inicial del fichero. Nos quedaría de la siguiente manera. F1: 238 -832 -18 -1 –84- 89-2-65-87-321-698-863 F2: 453- 3-13-98-7-374-16- 198-571- 539 F3: 68- 31-212-631- 37-81-217-354-987-254-368-693 Haremos distintas pasadas por cada uno de los ficheros de entrada e iremos haciendo grupos de elementos aprovechando el orden e introduciéndolos en los de salida. Acabaremos de hacer pasadas (iteraciones) cuando todos los datos nos queden en un solo fichero auxiliar. 1ª pasada 2ª pasada 3ª pasada 4ª pasada F1: 238 -832 -18 -1 –84- 89-2-65-87-321-698-863 F2: 453- 3-13-98-7-374-16- 198-571539 F3: 68- 31-212-631- 37-81-217-354-987- 254-368-693 5ª pasada F4: 68-238-453-832 2-16-65-87-198-254-321-368-571-693-698-863 F5: 3-13-18-31-98-212-631 539 F6: 1-7-37-81-84-89-217-354-374-987 Ya tenemos grupos de elementos ordenados en los ficheros F4, F5 y F6, pero aún no está ordenada la secuencia de entrada, con lo cual seguimos iterando. De esta manera en cada iteración vamos obteniendo cadenas mayores ordenadas. Continuamos haciendo pasadas como hacíamos antes pero ahora volcamos los datos sobre los ficheros F1, F2 y F3. 1ª pasada 2ª pasada F4: 68-238-453-832 2-16-65-87-198-254-321-368-571-693-698-863 F5: 3-13-18-31-98-212-631 539 F6: 1-7-37-81-84-89-217-354-374-987 F1: 1-3-7-13-18-31-37-68-81-84-89-98-212-217-238-354-374-453-631-832-987 F2: 2-16-65-87-198-254-321-368-539-571-639-698-863 F3: Vacío Aún no nos quedan todos lo elementos en un solo fichero, así que seguimos iterando, es decir, haciendo pasadas. En este caso solo nos queda una pasada por hacer y el fichero ya estará ordenado, ya que solo nos quedan dos secuencias. F1: 1-3-7-13-18-31-37-68-81-84-89-98-212-217-238-354-374-453-631-832-987 1ª Pasada F2: 2-16-65-87-198-254-321-368-539-571-639-698-863 2ª Pasada F3: Vacío En esta última ya nos quedarían todos los elementos ordenados en F4, con lo cual ya habríamos llegado al final, ya que en una sola pasada formamos un grupo con todos los elementos . 2.1 Características del Montículo Es el método mas eficiente de los métodos de ordenación que trabaja con árboles. Se basa en árboles binarios completo. Esto quiere decir, que para poder aplicar el método de ordenación del montículo sobre un vector de elementos, éste tendrá que tener un aspecto de árbol binario completo y estará lleno hasta el nivel N-1 (estará lleno de izada a derecha). Tendrá un aspecto parecido a este: Para representar un montículo en un vector lineal debe tenerse en cuenta lo siguiente: 1.- El hijo izquierdo de un nodo i se almacena en 2.- El hijo derecho de un nodo i se almacena en la posición 2*i+1. 3.- Dada una posición i del vector, el valor de dicha posición es > = que cualquiera de sus hijos. la posición 2*i. PROBLEMAS 3. Lo que nos piden en el ejercicio es una ordenación topológica pero haciendo una pequeña variante de la misma. const int infinito = 32767; //Ordenación topologica void Grafo::GradosdeEntrada (int GradodeEntrada[n+1]) { int i, j; for( j = 1; j <= n; j++) { GradodeEntrada[j] = 0; for (i = 1;i <= n; i++) if (A[i][j]!= infinito) GradodeEntrada[j]++; } } void Grafo::Ejercicio3 (int GradodeEntrada[n+1], int Tiempo[n+1]) { Cola<int> C1; int i,j,k,mayor; GradosdeEntrada (GradodeEntrada); for (i = 1; i <= n; i++) { if (GradodeEntrada[i] = = 0) C1.Poner(i); Tiempo[i]=0; } while (! C1.Vacia()) { i = C1.Primero(); C1.Quitar(); for( j = 1; j <= n; j++) if (A[i][j]!=infinito) if (GradodeEntrada[j] != 0) { GradodeEntrada[j] --; if (GradodeEntrada[j] = = 0) { C1.Poner(j); mayor=0; for(k=1;k<=n;k++) { if (A[k][j] != infinito && Tiempo[k] + A [k][j] > mayor) { mayor= Tiempo[k] + A [k][j]; Tiempo[j] = Tiempo[k] + A [k][j]; } } } } } } 4. Ejercicio de Backtracking const int n = 4; struct Reg { int protegida, soldado; }; - Protegida se inicializa a cero y soldado también. Menor se inicializa a 16 y act a cero. Candidatos: Las casillas del tablero solución: todas las casillas están protegidas (casillas=16) void ensayar ( Reg T[n+1][n+1], int &menor, int &act, int &casillas, Reg MejorSolucion[n+1][n+1]) { int i,j; for (i=1;i<=n;i++) for (j=1;j<=n;j++) { // La celda no está protegida if (T[i][j].protegida= =0) { ProtegerCeldas(T,i,j,casillas); T[i][j].soldado=1; act++; if(casillas = = 16) { if (act< menor) { menor = act; Copiar(T, MejorSolucion); } } DesprotegerCeldas(T,i,j,casillas); T[i][j].soldado=0; act--; } } } void ProtegerCeldas (int i, int j, Reg T[n+1][n+1], int &casillas) { if (i-1 >=1) T[i-1][j].amenaza++; if (i+1 <=n) T[i+1][j].amenaza++; if (j-1 >=1) T[i][j-1].amenaza++; if (j+1 <=n) T[i][j+1].amenaza++; T[i][j].amenaza++; } void DesprotegerCeldas (int i, int j, Reg T[n+1][n+1], int &casillas) { if (i-1 >=1) T[i-1][j].amenaza--; if (i+1 <=n) T[i+1][j].amenaza--; if (j-1 >=1) T[i][j-1].amenaza--; if (j+1 <=n) T[i][j+1].amenaza--; T[i][j].amenaza--; } 5. Ejercicio de AVL. Nos piden implementar la inserción de los árboles AVL. class Nodo; class Arbol { private: Nodo *a; bool hc; void AnadirR(int x, bool& hc); void ActualizarII(bool& hc); void ActualizarID(bool& hc); void RII(); void RID(); void RDD(); void RDI(); void RIIE(); void RDDE(); public: Arbol(); Arbol( Arbol al, int e, Arbol ad); Arbol(const Arbol & arb); ~Arbol() ; const Arbol& operator=(eonst Arbol& arb); void AnadirRecursivo (int e); }; class Nodo { private: int e; int fe; Arbol hi,hd; public: Nodo (Arbol ai,int x,int fe, Arbol ad); ~ Nodo(); Arbol& Gethi() {return hi;} Arbol& Gethd() {return hd;} int Getlnfo() {return e;} int GetFe() {return fe;} void Sethi(const Arbol& ai) {hi=ai;} void Sethd(const Arbol& ad) {hd=ad;} void Setlnfo(int d) {e=d;} void SetFe(int fe) {this->fe=fe;} }; void Arbol: :AnadirRecursivo (int x) { bool hc=false; //hc representa si crece en altura AnadirR(x, hc); } void Arbol::AnadirR(int x, bool& hc) { if (a == NULL) { a= new Nodo (Arbol(), x, 0, Arbol()); hc = true; } else if (a->Getlnfo() > x) { a->Gethi() .AnadirR(x, hc); if (hc) ActualizarII(hc) ; } else if (a->Getlnfo()<x) { a->Gethd() .AnadirR(x, hc); if (hc) ActualizarID(hc) ; } } void Arbol: :ActualizarII(bool &hc) { switch (a->GetFe()) { case +1: a->SetFe(0); hc=false; break; case 0: a->SetFe (-1) ; break; case -1: if (a->Gethi().a->GetFe() = = -l ) RII () ; else RID ( ) ; hc = false; break; } } void Arbol: :RII() { Nodo* p; p= a->Gethi() .a; a->Gethi().a =p ->Gethd() .a; p->Gethd() .a = a; a->SetFe(0) ; p->SetFe(0) ; a= p; } void Arbol::RID() { Nodo * pI, *p2; pl= a->Gethi() .a; p2=pl->Gethd() .a; a->Gethi() .a=p2->Gethd() .a; p2->Gethd() .a=a; pl->Gethd() .a=p2->Gethi() .a; p2->Gethi() .a= pI; if (p2->GetFe() = =-1) { a->SetFe (I) ; pl->SetFe(O) ; } Else if (p2->GetFe()= =1) { a->SetFe (0) ; pl->SetFe(-1) ; } else { a->SetFe(0); pl->SetFe(0) ; } p2->SetFe(0) ; a=p2; } // Actualizar tras insertar por la derecha void Arbol: :ActualizarID(bool &hc) { switch (a->GetFe()) { case -1: a->SetFe(0); hc = false; break; case 0: a->SetFe (+1) ; break; case +1: if (a->Gethd() .a->GetFe() = =l) RDD () ; else RDI() ; hc = false; break; } // del switch } void Arbol: :RDD() { Nodo *p; p= a->Gethd() .a; a->Gethd() .a=p->Gethi() .a; p->Gethi() .a=a; a->SetFe(O) ; p->SetFe(O) ; a = p; } void Arbol:: RDI() { Nodo * p1, *p2; pl= a->Gethd() .a; p2=pl->Gethi() .a; a->Gethd() .a= p2->Gethi() .a; p2->Gethi() .a=a; pl->Gethi() .a=p2->Gethd() .a; p2->Gethd() .a= p1; if (p2->GetFe()==+1) { a->SetFe(-1); pl->SetFe(O) ; } else if (p2->GetFe() = = -1) { a->SetFe (O) ; pl->SetFe( l) ; } else { a->SetFe(0); pl->SetFe(0) ; } a=p2; a->SetFe(0) ; }