jueves, 14 de julio de 2011

ultima tarea arboles

este es el cogigo fuente de arboles modificado apara que tambien elimine nododos
pero tiene un error
(pero no compila)

#include "bool.h"
#include<stdio.h>

#define DEBUG 1

// NOTA: faltan implementar las rotaciones
// dobles; por ahora no balancea bien

// un nodo de ruteo no cuenta duplicados
#define NO_VALIDO -1

#ifdef DEBUG
int next = 0;
#endif

struct nodo_de_arbol {
char dato;
int altura;
int contador;
#ifdef DEBUG
int id;
#endif
struct nodo_de_arbol* padre;
struct nodo_de_arbol* izq; // hijo
struct nodo_de_arbol* der; // otro hijo
};
typedef struct nodo_de_arbol nodo;

void borra(nodo* n) {
if (n == NULL) {
return;
} else {
borra(n->izq);
borra(n->der);
free(n);
}
return;
}

void muestra(nodo* n) {
if (n == NULL) {
return; // caso base de recursion
} else {
muestra(n->izq);
#ifdef DEBUG
if (n->izq != NULL && n->der != NULL) {
printf("[%c, %d <%d / %d, %d>] ", 
n->dato, n->altura, n->id,
n->izq->id, n->der->id);
} else {
printf("(%c, %d <%d> #%d) ", 
n->dato, n->altura, n->id,
n->contador);
}
#else
if (n->izq == NULL && n->der == NULL) {
printf("%c[%d] ", n->dato, n->contador);
}
#endif
muestra(n->der);
}
return;
}

void balancea(nodo* n, nodo** raiz) {
int ai, ad, max, min, aalt, balt;
nodo* t = NULL;
nodo* u = NULL;
nodo* v = NULL;
nodo* a = NULL;
nodo* b = NULL;
nodo* p = NULL;
nodo* x1 = NULL;
nodo* x2 = NULL;

if (n == NULL) {
#ifdef DEBUG
printf("Ya topamos con la raiz.\n");
#endif
return;
}
if (n->izq == NULL ||
n->der == NULL) {
#ifdef DEBUG
printf("No se puede sin hijos.\n");
#endif
return;
}

t = n; // nodo actual
assert(t != NULL);

#ifdef DEBUG
printf("Checando balance en %c (alt. %d).\n",
t->dato, t->altura);
#endif

u = n->izq; // hijo izquierdo
assert(u != NULL);
v = n->der; // hijo derecho
assert(v != NULL);

ai = u->altura;
ad = v->altura;

#ifdef DEBUG
printf("Hijos %c (alt. %d) y %c (alt. %d).\n",
u->dato, ai, v->dato, ad);
#endif

max = (ai > ad) ? ai : ad;
min = (ai > ad) ? ad : ai;

if (max + 1 != t->altura) {
t->altura = max + 1; // actualizar altura
}

if (max - min > 1) { // balancear
p = t->padre; // padre del actual

#ifdef DEBUG
printf("%c a altura %d requiere balanceo.\n", 
t->dato, t->altura);
printf("Entrando tenemos:\n");
if (p != NULL) {
printf("p = %d, ", p->id);
} else {
printf("p = NULL, ");
}
printf("t = %d, \n", t->id);
printf("u = %d, v = %d, \n", 
u->id, v->id);
#endif

if (ai <= ad - 2) {        // si hay demasiada altura a la der       // => voltear "peso" hacia la izq.
a = v->izq;
b = v->der;
assert(a != NULL);
assert(b != NULL);
aalt = a->altura;
balt = b->altura;

#ifdef DEBUG
printf("a = %d, b = %d, \n", 
a->id, b->id);
#endif

if (aalt <= balt) { // rotacion simple izq  printf("Simple izquierda.\n");  if (p != NULL) {    // v debe reemplazar a t como hijo    if (p->izq == t) {
p->izq = v;
} else { // era derecho 
p->der = v;
}
} else {
// v es ahora raiz
*raiz = v;
}
// el padre de t sera padre de v
v->padre = p;
// printf("Arreglado hacia arriba.\n");

// v ahora es hijo izq de t
// t es padre de v
v->izq = t;
t->padre = v;
// el hijo der de t no cambia
// printf("Arreglado entre t y v.\n");

// a va a ser hijo derecho de t
// t va a ser padre de a
t->der = a;
a->padre = t;
// printf("Arreglado entre a y t.\n");

#ifdef DEBUG
if (p != NULL) {
printf("v = %d es hijo de p = %d,\n",
v->id, p->id);
}
printf("t = %d = %d es hijo de v = %d,\n",
t->id, v->izq->id, v->id);
printf("a = %d = %d es hijo de t = %d\n",
a->id, t->der->id, t->id);
printf("b = %d = %d es hijo de v = %d,\n",
b->id, v->der->id, v->id);
printf("u = %d = %d es hijo de t = %d.\n",
u->id, t->izq->id, t->id);
#endif
// para ni u ni b nada cambia
} else { 
printf("Simple derecha-izquierda.\n");
x1 = a->izq;
assert(x1 != NULL);
x2 = a->der;
assert(x2 != NULL);

if (p != NULL) {
if (p->izq == t) {
p->izq = a; // w
} else { // era der.
p->der = a;
}
} else { // t era raiz
*raiz = a; // avisar main
}
v->padre = a;
a->der = v;
t->padre = a;
a->izq = t;
v->izq = x2;
x2->padre = v;
t->der = x1;
x1->padre = t;
}
} else if (ai >= ad + 2) {
// voltear hacia la derecha
a = u->izq;
b = u->der;
assert(a != NULL);
assert(b != NULL);
aalt = a->altura;
balt = b->altura;
if (aalt >= balt) { 
printf("Simple derecha.\n");
if (p != NULL) {
if (p->izq == t) {
p->izq = u;
} else { // era derecho 
p->der = u;
}
} else {
// cambiando la raiz para ser u
*raiz = u;
}
u->padre = p;
// printf("Arreglado hacia arriba.\n");
u->der = t;
t->padre = u;
// printf("Arreglado entre t y u.\n");
t->izq = b;
b->padre = t;
// printf("Arreglado entre b y t.\n");
} else { // (aalt < balt)  printf("Doble izquierda derecha.\n");  x1 = b->izq;
assert(x1 != NULL);
x2 = b->der;
assert(x2 != NULL);

if (p != NULL) {
if (p->izq == t) {
p->izq = b; // w
} else { // era der.
p->der = b;
}
} else { // t era raiz
*raiz = b; // avisar main
}
u->padre = b;
b->izq = u;
t->padre = b;
b->der = t;
u->der = x1;
x1->padre = u;
t->izq = x2;
x2->padre = t;
}
}
if (p != NULL) {
balancea(p, raiz);
}
} else {
#ifdef DEBUG
printf("%c esta bien (%d vs. %d).\n", 
n->dato, ai, ad);
#endif
// siempre checa hasta la raiz
balancea(n->padre, raiz);
}
return;
}

bool agrega(char dato, nodo* arbol, nodo** n) {
nodo* nuevo;
nodo* reemplazo;
char ruteo;
if (arbol == NULL) {
// caso especial de no tener nada aun
nuevo = (nodo*)malloc(sizeof(nodo));
nuevo->contador = 1;
#ifdef DEBUG
nuevo->id = next++;
#endif
nuevo->altura = 1; // como hoja
nuevo->dato = dato;
nuevo->padre = NULL;
nuevo->izq = NULL;
nuevo->der = NULL;
*n = nuevo; // nueva raiz
return TRUE;
} else {
if (arbol->izq == NULL &&
arbol->der == NULL) { // si es hoja

if (arbol->dato == dato) {
// iguales; agregar duplicidad
arbol->contador++;
return FALSE;
}

#ifdef DEBUG
printf("Agregando %c en %c.\n",
dato, arbol->dato);
#endif

ruteo = (arbol->dato < dato ?          arbol->dato : dato);

nuevo = (nodo*)malloc(sizeof(nodo));
nuevo->contador = 1;
#ifdef DEBUG
nuevo->id = next++;
#endif
nuevo->altura = 1; // como hoja
nuevo->dato = dato;
nuevo->padre = arbol;
nuevo->izq = NULL;
nuevo->der = NULL;

reemplazo = (nodo*)malloc(sizeof(nodo));
reemplazo->contador = arbol->contador;
arbol->contador = NO_VALIDO;
#ifdef DEBUG
reemplazo->id = next++;
#endif
reemplazo->altura = 1; // como hoja
reemplazo->dato = arbol->dato;
reemplazo->padre = arbol;
reemplazo->izq = NULL;
reemplazo->der = NULL;

if (dato < arbol->dato) {
arbol->izq = nuevo;
arbol->der = reemplazo;
} else if (dato > arbol->dato) {
arbol->der = nuevo;
arbol->izq = reemplazo;
}

arbol->dato = ruteo;
arbol->altura = 2;
balancea(arbol->padre, n);
} else {
if (dato <= arbol->dato) {
agrega(dato, arbol->izq, n);
} else { // mayor
agrega(dato, arbol->der, n);
}
}
}
return TRUE;
}
printf("desea elimiar un nodo");
printf("dame al altura del nodo al que desea eliminar");
scanf("%d %d", nodos, alura);
dato = getchar();
if (!isspace(dato)) {
if (eliminar(dato, raiz, &raiz)) {
contador++;}
printf("eliminacion completada");
else {printf("el nodo seleccionado no existe");
if (raiz != NULL) {
printf("\nCon %d nodos, altura %d: \n",
contador, raiz->altura);

int main(int argc, char** args) {
nodo* raiz = NULL;
char dato;
int contador = 0;

do {
dato = getchar(); // lee un caracter
if (!isspace(dato)) {
if (agrega(dato, raiz, &raiz)) {
contador++;
}
if (raiz != NULL) {
printf("\nCon %d nodos, altura %d: \n",
contador, raiz->altura);
muestra(raiz);
printf("\n");
} else {
printf("No hay nada.\n");
}
}
} while (dato != '!'); // parar despues de !
borra(raiz);

return 1;
}
************************************************************************************************
PUNTOS EXTRAS
este es el codigo de funciones lo e modificado para que fuera un juego interactivo con el usuario
este es el codigo--->
#include 
#include 
#include "bool.h"
#include "entrada.h"

int suma(int a, int b) {
  return (a + b);
}

int resta(int a, int b) {
  return (a - b);
}

int multiplica(int a, int b) {
  return (a * b);
}

int divide(int a, int b) {
  return (a / b);
}

int residuo(int a, int b) {
  return (a % b);
}

// tipo de dato para apuntador a funcion
typedef int (*rutina)(int, int);
typedef void (*otracosa)(char, int);

int main(int argc, char** args) {
  rutina *r = NULL;
  otracosa* o = NULL;
  int x, y;
  char = juego
  int min = 1;
  int max = 10;
  
  if (argc > 2) {
    min = atoi(args[1]);
    max = atoi(args[2]);
    if (min > max) {
      printf("Pon primero el minimo.\n");
      return;
    } else if (min <= 0) {
      printf("Deben ser positivos. Sorry.\n");
      return;
    }
  }

  srand(time(0)); // semilla para rng

  r = (rutina*)malloc(sizeof(rutina)*5);
  r[0] = &suma;
  r[1] = &resta;
  r[2] = &multiplica;
  r[3] = ÷
  r[4] = &residuo;

  while (TRUE) {
        printf("dime que cres que va a salir suma, resta, multiplicacion, divison o residuo);
        printf("dame una opcion", juego);
        scanf("%d", juego);
        switch case(juego){
               case 0: printf("as elegido suma--- veamos cual es la respuesta")
               break;
               case 1: printf("as elegido resta---veamos cual es la respuesta");
               break;
               case 2: printf("as elegido multiplicacion---veamos cual es la respuesta");
               break;
               case 3: printf("as elegido divison---vemaos cual es la respuesta");
               break;
               case 4: printf("as elegido residuo");
               break;
               default: printf("opcion no valida");
               break;
               printf("cres poder ganar");
               printf("a jugar se a dicho");
               printf("\n);
               printf("Dame el primer valor:\n");
    x = pide_numero(min, max);
    printf("Dame el segundo valor:\n");
    y = pide_numero(min, max);
    printf("Salio %d.\n", r[rand()%5](x, y));
    if(juego = r[rand()%5](x, y)){
             printf("felisidades si era lo opcion que seleccionaste");}
             else {printf("lo sentimos pero perdiste vuelve a intentarlo");
    printf("Quieres mas? (s/n): ");
    if (pide_opcion("sn") == 'n') {
      break; // ya no
    }
  }
  free(r);
  // modificado del archivo orginal para que el programa se comvirtiera en un juego con el usuario//

  return 1;
}

1 comentario:

  1. Siempre no lo arreglaste, entonces. Interesante que ÷ se puso ÷.

    El juego es un poco raro; tendría más sentido ver primero el resultado y luego tener que saber cuál operación fue :P

    Te pongo +5 por estos dos intentos.

    ResponderEliminar