Está en la página 1de 15

CAPTULO 10

PILAS Y SUS APLICACIONES


EJEMPLO 10.3
Paso de notacin infija a notacin postifija:

la expresin 2 + 4 * 3 * ( 1 + 2 ) en notacin postfija es 2 4 3 * 1 2 + * +


la expresin 3 + 4 * 5 ^ ( 1 / 2 ) en notacin postfija es 3 4 5 1 2 / ^ * +
la expresin 6.25 * 4 + 5.7 en notacin postfija es 6.25 4 * 5.7 +

PROBLEMAS RESUELTOS

10.1.
#include <stdio.h>
#include <stdlib.h>
typedef float TipoElemento;
typedef struct UnNodo
{
TipoElemento e;
struct UnNodo *sig;
}Nodo;
typedef Nodo Pila;
int EsVaciaP(Pila *P)
{
return P == NULL;
}
void VaciaP(Pila** P)
{
*P = NULL;
}
void AnadeP(Pila** P,TipoElemento e)
{
Nodo * NuevoNodo;
NuevoNodo=(Nodo*)malloc(sizeof(Nodo));
NuevoNodo -> e = e;
NuevoNodo->sig= (*P);
*P=NuevoNodo;
}
TipoElemento PrimeroP(Pila *P)
{
TipoElemento Aux;
if (EsVaciaP(P))
{
puts("Se intenta sacar un elemento en pila vaca");
}

exit (1);

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

Aux = P->e;
return Aux;
}
void BorrarP(Pila** P)
{
Pila *NuevoNodo;
if (EsVaciaP(*P))
{
puts("Se intenta sacar un elemento en pila vaca");
exit (1);
}
NuevoNodo=(*P);
(*P) = NuevoNodo->sig;
free(NuevoNodo);
}

10.2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int PrioridadDentro(char opdor)
{
switch (opdor)
{
case '(': return 0; case '^': return 3; case '/': return 2;
case '*': return 2; case '+': return 1; case '-': return 1;
}
return 0;
}
int PrioridadFuera(char opdor)
{
switch (opdor)
{
case '(': return 5;
case '^': return 4; case '/': return 2;
case '*': return 2;
case '+': return 1; case '-': return 1;
}
return 0;
}
int Operador( char ch)
{
return ( ch=='('||ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='^' );
}
void Postfija(char Linea[80],char post[80])
{
Pila *P;
char ch, aux[2];
int i, Apilado ;
VaciaP(&P);

Pilas y sus aplicaciones

aux[1] = '\0' ;
post[0] = '\0';
for (i = 0; i < strlen(Linea); i++)
if (Operador(Linea[i]))
{
Apilado = 0;
while (!Apilado)
if (EsVaciaP(P))
{
AnadeP(&P,Linea[i]);
Apilado = 1;
}
else
{
ch = PrimeroP(P);
if(PrioridadDentro(ch) >= PrioridadFuera(Linea[i]))
{
aux[0] = ch;
strcat(post,aux);
BorrarP(&P);
}
else
{
AnadeP(&P,Linea[i]);
Apilado = 1;
}
}
}
else
if (Linea[i] == ')' )
{
ch = PrimeroP(P);
BorrarP(&P);
while (ch != '(')
{
aux[0] = ch;
strcat(post,aux);
ch = PrimeroP(P);
BorrarP(&P);
}
}
else
/*(operando(Linea[i]*/
{
aux[0] = Linea[i];
strcat(post,aux);
}
while(!EsVaciaP(P))
{
ch = PrimeroP(P);
BorrarP(&P);
aux[0] = ch;
strcat(post,aux);
}
}

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

void main (void)


{
char post[80], Linea[80];
puts(" expresion a pasar a Postfija\n");
gets(Linea);
Postfija(Linea,post);puts("\n Postfija\n");puts(post);
}

10.3
float valor(char c)
{
return (float) c;
}
float evaluar ( char post[80])
{
float valor1, valor2,valor3;
int i;
Pila *P;
VaciaP(&P);
for(i = 0; i<strlen(post); i++)
if (operador(post[i]))
{
valor2 = PrimeroP(P);
BorrarP(&P);
valor1 = PrimeroP(P);
BorrarP(&P);
switch (post[i])
{
case '^' : valor3 = pow(valor1,valor2); break;
case '/' : valor3 = valor1/valor2; break;
case '*' : valor3 = valor1*valor2; break;
case '+' : valor3 = valor1+valor2; break;
case '-' : valor3 = valor1-valor2;
}
AnadeP(&P,valor3);
}
else
{
valor3 = valor(post[i]);
AnadeP(&P,valor3);
}
valor1 =PrimeroP(P);
BorrarP(&P);
return valor1;
}

10.4
#include <stdio.h>
#include <stdlib.h>
enum Tpalo {oros, copas, espadas, bastos};
enum Tvalor { as, dos, tres, cuatro, cinco, seis, siete, sota, caballo, rey};

Pilas y sus aplicaciones

struct Tcarta
{
Tpalo palo;
Tvalor valor;
} ;
typedef Tcarta TipoElemento;
typedef struct unnodo
{
TipoElemento e;
struct unnodo *sig;
}Nodo;
typedef Nodo Pila;
typedef Pila Pila_de_Cartas ;
void Barajar_Las_Cartas(int a[40])
{
int aux[40], i, j, k, h;
for (i = 0; i < 40; i++)
aux[i] = i;
j = 40;
i = 0;
randomize();
while ( j > 0)
{
k = random(j);
a[i] = aux[k];
i++;
for (h = k; h < j - 1; h++)
aux[h] = aux[h + 1];
j --;
}
}

/*Se encarga de barajar las cartas */

void EscribeCarta(Tcarta ca)


{
printf("%3d",(ca.palo-oros)*10 + ca.valor-as);
}
void LeeCarta(Tcarta *ca, int i )
{
/*Trasforma el nmero entero i en una carta */
int num1, num2, j;
/*Cada nmero contiene dos dgitos que corresponden con el palo y le valor de carta*/
num1 = i % 10;
num2 = i/ 10;
ca->palo = oros;
for (j = 0; j < num2; j++)
ca->palo++;
ca->valor = as;
for (j = 0; j < num1; j++)
ca->valor++;
}
void LeeMazo(Pila_de_Cartas ** maz,int n[40])
{
Tcarta car;

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

int i;
VaciaP(maz);
printf("mazo\n");
for (i = 0; i < 40; i++)
{
LeeCarta(&car, n[i]);
EscribeCarta(car);AnadeP(maz, car);
};
printf("fin mazo\n");
}
void ColocaCarta(Pila_de_Cartas **des, Pila_de_Cartas * mon[4], int *coloca)
{
/*Coloca todas las cartas que puede dedescartes en los montones de las bases*/
int Seguimos, Valida;
/*continua colocando y puede colocarse*/
Tcarta car;
/*carta de descartes */
Tcarta ultima;
/* carta de las bases*/
Seguimos = 1;
/*Mientras haya cartas en descartes y debamos seguir*/
while (! EsVaciaP(*des)&& Seguimos)
{
car = PrimeroP(*des);
if (EsVaciaP(mon[car.palo]))
Valida = car.valor == as;
/*la base est vaca. Se valida que sea un as*/
else
{
/*la base tiene cartas.Valida si es la siguiente a la ltima*/
ultima = PrimeroP(mon[car.palo]) ;
Valida = ultima.valor+1== car.valor;
}
if (Valida)
{
/*Pasa carta a la base y se sigue */
printf("se coloca carta");
EscribeCarta(car);printf("\n");
AnadeP(&(mon[car.palo]), car);
BorrarP(des);
*coloca = 1;
}
else
Seguimos = 0;
}
}
void DaVuelta( Pila_de_Cartas **Monton, Pila_de_Cartas **Descartes)
{
/*a la vuelta a la pila d en la pila
m */
Tcarta Car;
while (! EsVaciaP(*Descartes))
{
Car=PrimeroP(*Descartes);
/*extrae carta del montn de descartes */
EscribeCarta(Car);
BorrarP(Descartes);
AnadeP(Monton, Car);
/*Inserta la carta en el mazo*/
}
}
void main(void)
{

Pilas y sus aplicaciones

Pila_de_Cartas *Monton,*Descartes, *mon[4];/*mazo descartes y bases*/


int FinDelSolitario, Colocada, AlgunaColocada, i;
Tcarta CartaAux;
/*auxiliar para cartas*/
int Numeros_de_Cartas[40];
/*vector con cartas barajadas*/
Barajar_Las_Cartas(Numeros_de_Cartas);
for (i = 0 ; i < 4; i++)
/*Pone las bases vacias */
VaciaP(&mon[i]);
LeeMazo(&Monton, Numeros_de_Cartas);
/*Realiza la lectura inicial del mazo*/
FinDelSolitario = 0;
while (! FinDelSolitario)
{
VaciaP(&Descartes);
Colocada = 0;
AlgunaColocada = 0;
while (! EsVaciaP(Monton))
{
/*Pasa una pareja al montn de descartes. Si solo hay una debe pasarla*/
CartaAux=PrimeroP(Monton);
BorrarP(&Monton);
AnadeP(&Descartes, CartaAux);
if (!EsVaciaP(Monton))
{
CartaAux = PrimeroP(Monton);
BorrarP(&Monton);
AnadeP(&Descartes, CartaAux);
}
ColocaCarta(&Descartes, mon, &Colocada);
/*pasa cartas a las bases*/
AlgunaColocada = AlgunaColocada || Colocada;
}
printf("\n vuelta al mazo\n"); DaVuelta(&Monton, &Descartes);
printf("\n");
FinDelSolitario = !AlgunaColocada ||EsVaciaP(Monton);
}
if (EsVaciaP(Monton))
printf(" solitario realizado\n");
else
printf(" solitario fallido\n");
}

10.5
void DestruyeLista(Lista
{
Lista *Auxiliar;
while (*p != NULL)
{
Auxiliar = *p;
(*p) = (*p)->sig;
free(Auxiliar);
}
}

**p)

void EscribeListaAlReves(Lista *p)


{
if (p!=NULL)
{

/*escribe la pila al revs

recursivamente*/

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

EscribeListaAlReves(p->sig);
printf("%c",p->el);
}
}
void SumarListasDeNumeros (Lista **Total, Lista *Sumando)
{
/* Total y sumando nunca son vacios*/
int acarreo, el ;
Lista *Nuevo, *TotalAux, *AntetiorTotal, *s;
printf("Total parcial:");
EscribeListaAlReves (*Total);
printf("\n'Sumando: \n");
EscribeListaAlReves(Sumando); printf("\n");
acarreo = 0;
TotalAux = *Total;
AntetiorTotal = NULL;
s = Sumando;
while ((TotalAux != NULL) && (s != NULL))
{
/* suma de los dos*/
el = TotalAux->el + s->el + acarreo - 2 * 48;
TotalAux->el = el% 10 + 48;
acarreo = el / 10;
AntetiorTotal = TotalAux;
TotalAux = TotalAux->sig; s = s->sig;
}
while (s !=NULL)
{
/* suma de s*/
el = s->el - 48 + acarreo;
Nuevo =(Lista*)malloc(sizeof(Lista));
Nuevo->el = el % 10 + 48;
acarreo = el / 10;
Nuevo->sig = NULL;
AntetiorTotal->sig = Nuevo;
AntetiorTotal = Nuevo;
s = s->sig;
}
while (TotalAux !=NULL)
{
/* suma de TotalAux*/
el = acarreo + TotalAux->el - 48;
acarreo = el / 10; TotalAux->el = el %10 + 48;
AntetiorTotal = TotalAux; TotalAux = TotalAux->sig ;
}
if (acarreo == 1)
{
Nuevo =(Lista*)malloc(sizeof(Lista));
Nuevo->el = '1';
Nuevo->sig = NULL;
AntetiorTotal->sig = Nuevo;
}
printf("Nuevo Total Parcial: \n");
EscribeListaAlReves(*Total); printf("\n");
}
void main (void)
{

Pilas y sus aplicaciones

Lista *Total, *Sumando;


FILE *f;
char el ;
if ((f = fopen("numeros.dat","r+t")) == NULL)
{
puts("error de apertura texto");
exit(1);
}
Total = NULL;
Sumando = NULL;
if (!feof(f))
{
el = getc(f);
while (el != '\n') /*fin de linea*/
{
AnadeP(&Total,el);
el = getc(f);
}
EscribeListaAlReves(Total);
printf(" primer paso\n");
while (!feof (f))
{
el = getc(f);
while (el != '\n')
{
AnadeP(&Sumando,el);
el = getc(f);
}
SumarListasDeNumeros (&Total, Sumando);
DestruyeLista (&Sumando);
}
}
else
printf("Fichero de datos vaco");
fclose (f);
}

10.6
void Hanoi(int n, int d, int h, int u)
{
if (n == 1)
printf(" llevo disco %3d del palo %3d al palo %3d\n",n,d,h);
else
{
Hanoi(n - 1, d, u, h);
printf(" llevo disco %3d del palo %3d al palo %3d\n",n,d,h);
Hanoi(n - 1, u, h, d) ;
}
}
void Hanoinr(int n, int d, int h,int
{
elemento e, e1;

u)

/* fin de linea*/

10

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

Pila *p;
VaciaP(&p);
e.n =n ; e.d = d;
e.h = h;
e.u = u;
e.estado = uno;
AnadeP(&p, e);
while (! EsVaciaP(p))
{
e = PrimeroP(p);
BorrarP(&p);
switch (e.estado)
{
case uno:
{
if (e.n == 1)
printf(" llevo disco %3d del palo %3d al palo %3d\n",e.n,e.d,e.h);
else
{
e1.n = e.n-1;
e1.estado = uno;
e1.d = e.d;
e1.h = e.u;
e1.u = e.h;
e.estado = dos;
AnadeP(&p, e);
AnadeP(&p, e1);
}
break;
}
case dos:
{
printf(" llevo disco %3d del palo %3d al palo %3d\n",e.n,e.d,e.h);
e1.n = e.n - 1;
e1.estado = uno;
e1.d = e.u;
e1.h = e.h;
e1.u = e.d;
AnadeP(&p, e1);
}
}
}
}
void main(void)
{
Hanoinr(4, 1, 2, 3);
}

10.7
#define n 5
enum Estados {Ninguno, Incluido, Excluido} ;

Pilas y sus aplicaciones

11

struct elemento
{
Estados estado;
} ;
typedef elemento TipoDato;
int Pesos[n], OabjetivoAalcanzar;
void Inicializa()
{
Pesos[0]= 7; Pesos[1] = 5; Pesos[2] = 4; Pesos[3] = 4; Pesos[4] = 1;
OabjetivoAalcanzar = 10;
}
void MochilaExacta(int OabjetivoAalcanzar,int i, int *Solucion)
{
int Encontrado, Posibilidad;
/*Se termina con xito siObjetivo=0 o bien con fallo sio Objetivo<0 o bien i=n*/
if (( OabjetivoAalcanzar <= 0) || (i== n))
if (OabjetivoAalcanzar == 0 )
/*solucin*/
*Solucion = 1;
else ;
/*no hacer nada porque Objetivo<0 o bien i=n*/
else
{
Posibilidad = 0;
Encontrado = 0;;
do
{
Posibilidad ++;
switch (Posibilidad)
{
case 1:
/*Inclusin*/
MochilaExacta(OabjetivoAalcanzar-Pesos[i], i+1, &Encontrado);
if( Encontrado)
printf("%d ",Pesos[i]);
*se ha inluido y se tiene solucin*/
break;
case 2:
/*exclusin*/
MochilaExacta(OabjetivoAalcanzar, i+1, &Encontrado);
/*aunque Encontrado sea verdadero, no hace falta hacer nada*/
}
}
while (!((Posibilidad == 2) || Encontrado));
*Solucion = Encontrado;
}
}
void MochilaExacta_N_R(int OabjetivoAalcanzar)
{
int i, Solucion;
Pila
*P;
elemento e, e1;
i = 0;
Solucion = 0;
e.estado = Ninguno;
VaciaP(&P);
AnadeP(&P, e);
/*Asigna el valor inicial a la pila P considerando Pesos[0]*/

12

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

while (! EsVaciaP(P))
{
e = PrimeroP(P);
BorrarP(&P);
if (Solucion)
/*si se tie ne ya una solucin entonces escribirla*/
{
if (e.estado == Incluido)
printf("%d \n",Pesos[i]);
/*{solo se escribe algo si est incluido*/
i --;
/*retrocede*/
}
else
/*solucion es false*/
if (((OabjetivoAalcanzar <= 0) && (e.estado == Ninguno)) || (i == n))
{
if (OabjetivoAalcanzar == 0)
Solucion = 1;
/*siempre se obtiene solucin*/
i --;
/*el i no se ha probado. Se retrocede en la recursividad*/
}
else
/*no hay decisin se considera el estado del candidato actual*/
switch (e.estado)
{
case Ninguno:
/*Primero se incluye avance de la recursividad*/
OabjetivoAalcanzar -= Pesos[i];
i ++;
e1.estado=Incluido;
AnadeP(&P, e1);
e1.estado = Ninguno;
AnadeP(&P, e1);
/* se va al comienzo*/
break;
case Incluido:
/*Ahora se excluye avance de la recursividad*/
/*se retrocede i--; en opcin else de q*/
OabjetivoAalcanzar += Pesos[i];
/*como se quit hay que sumarlo*/
i ++;
e1.estado=Excluido;
AnadeP(&P, e1);
e1.estado=Ninguno;
AnadeP(&P, e1);
break;
case Excluido:
/*la eleccin actual no dio resultado se ha terminado la recursividad*/
i--;
}
}
}
void main (void)
{
int
Solucion;
Inicializa();
MochilaExacta(OabjetivoAalcanzar, 0, &Solucion);
if( Solucion)
printf("Solucin dada para Objetivo = %d \n", OabjetivoAalcanzar);
Solucion = 0;
OabjetivoAalcanzar = 10;
MochilaExacta_N_R(OabjetivoAalcanzar);
if (Solucion)

Pilas y sus aplicaciones

printf(" se encontr solucin");


}

10.8.
#define nn 8
enum Estados {uno, dos} ;
struct elemento
{
Estados Estado;
int Posibilidad;
};
typedef elemento TipoElemento;
int Contador, i, j, x, y, DespX[8],DespY[8],Tablero[8][8], n ,nCuadrado;
void Escribesolucion()
{
int i, j;
for(i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%5d",Tablero[i][j]);
printf("\n");
};
printf("solucin %3d\n",Contador);
};
void ensayartodas()
{
int Posibilidad = -1;
do
{
Posibilidad++;
x += DespX[Posibilidad];
y += DespY[Posibilidad];
if ((x < n) && (y < n) && (x >= 0) && (y >= 0))
if (Tablero[x][y] == 0)
{
Tablero[x][y ] = i;
if (i < nCuadrado)
{
i ++;
ensayartodas();
i --;
}
else
{
Escribesolucion();
Contador++;
}
Tablero[x][y] = 0;
}
x -= DespX[Posibilidad];
y -= DespY[Posibilidad];
}
while(Posibilidad<8-1);

13

14

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

}
void ensayartodasnr()
{
int Posibilidad,colocado;
Pila *P;
elemento e, e1;
VaciaP(&P);
e.Posibilidad = -1;
e.Estado = uno;
AnadeP(&P, e);
while (! EsVaciaP(P))
{
e1=PrimeroP(P);
BorrarP(&P);
e = e1;
switch (e.Estado)
{
case uno:
{
Posibilidad = e.Posibilidad;
colocado = 0;
while (! colocado && (Posibilidad < 8-1))
{
Posibilidad++;
x += DespX[Posibilidad];
y +=DespY[Posibilidad];
if ((x < n) && (y < n) && (x >= 0) && (y >= 0))
if (Tablero[x][y] == 0)
colocado = 1;
if (! colocado)
{
x -= DespX[Posibilidad];
y -= DespY[Posibilidad];
}
}
if (colocado)
{
Tablero[x][y] = i;
if (i == nCuadrado)
{
Escribesolucion();
Contador ++;
e.Estado = dos;
e.Posibilidad = Posibilidad;
i ++;
AnadeP(&P, e);
}
else
{
e.Estado = uno;
e.Posibilidad = Posibilidad;
AnadeP(&P, e);
e.Estado = dos;
e.Posibilidad = Posibilidad;

Pilas y sus aplicaciones

AnadeP(&P, e);
e.Estado = uno;
e.Posibilidad = -1;
AnadeP(&P, e);
i ++;
}
}
break;
}
case dos:
{
Posibilidad = e.Posibilidad;
Tablero[x][y] = 0;
i --;
x -= DespX[Posibilidad];
y -= DespY[Posibilidad];
}
}
}
}
void main(void)
{
printf("valor de n ");
scanf("%d",&n);
nCuadrado = n * n;
DespX[0] = 2;
DespY[0] =
DespX[2] = -1; DespY[2] =
DespX[4] = -2;
DespY[4] =
DespX[6] = 1;
DespY[6] =
Contador=1;
for (i = 0; i < n; i++)
for (j = 0;j < n; j++)
Tablero[i][j] = 0;
Tablero[0][0] = 1;
i = 2;
x = 0;
y = 0;
/*ensayartodasnr();*/
ensayartodas();
}

1;
2;
-1;
-2;

DespX[1]
DespX[3]
DespX[5]
DespX[7]

= 1;
= -2;
= -1;
= 2;

DespY[1]
DespY[3]
DespY[5]
DespY[7]

=
=
=
=

2;
1;
-2;
-1;

15

También podría gustarte