elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Arreglado, de nuevo, el registro del warzone (wargame) de EHN


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Problema manejo de Pila
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Problema manejo de Pila  (Leído 5,161 veces)
erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Problema manejo de Pila
« en: 12 Febrero 2014, 23:47 pm »

Hola que tal estoy teniendo algunos problemas para mostrar los valores de una pila una vez se ha borrado un valor, y posteriormente luego cuando voy a borrar los nodos restantes. Aqui va el codigo, espero una ayuda gracias:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. typedef struct nodo
  5. {
  6.    int num;
  7.    struct nodo *sig;
  8. }Nodo;
  9.  
  10. typedef struct pila
  11. {
  12.    Nodo *primero;
  13.    Nodo *ultimo;
  14. }Pila;
  15.  
  16. void resetPila( Pila * );
  17. int estaVacia( Pila * );
  18. void agregarValor( Pila *, int );
  19. void mostrarPila( Pila * );
  20. int borrarTope( Pila * );
  21. void borrarTodo( Pila * );
  22.  
  23. int main( int argc, char* args[] )
  24. {
  25.    Pila miPila;
  26.    int valor, opcion;
  27.  
  28.    resetPila( &miPila );
  29.  
  30.    do
  31.    {
  32.        system("cls");
  33.        printf("Ingrese una opcion\n");
  34.        printf("\n1.- Ingresar numero a la pila");
  35.        printf("\n2.- Mostrar numeros en la pila");
  36.        printf("\n3.- Eliminar tope de la pila");
  37.        printf("\n4.- Salir\n\n");
  38.        scanf("%d", &opcion);
  39.  
  40.        switch( opcion )
  41.        {
  42.            case 1:
  43.                printf("Ingrese el numero para la pila: ");
  44.                scanf("%d", &valor);
  45.                agregarValor( &miPila, valor );
  46.                system("pause");
  47.            break;
  48.  
  49.            case 2:
  50.                if( estaVacia( &miPila ) == 1 )
  51.                    printf("\nLa pila esta vacia");
  52.                else
  53.                    mostrarPila( &miPila );
  54.                system("pause");
  55.            break;
  56.  
  57.            case 3:
  58.                if( estaVacia( &miPila ) == 1 )
  59.                    printf("\nLa pila esta vacia");
  60.                else
  61.                    printf("Se elimino el numero %d\n\n", borrarTope( &miPila ));
  62.                system("pause");
  63.            break;
  64.  
  65.            case 4:
  66.                if( estaVacia( &miPila ) == 0 )
  67.                    borrarTodo( &miPila );
  68.            break;
  69.        }
  70.  
  71.    }while( opcion != 4 );
  72.  
  73.  
  74. return 0;
  75. }
  76.  
  77. void resetPila( Pila *miPila )
  78. {
  79.    miPila->primero = NULL;
  80.    miPila->ultimo = NULL;
  81. }
  82.  
  83. int estaVacia( Pila *miPila )
  84. {
  85.    if( miPila->primero == NULL )
  86.        return 1;
  87.    else
  88.        return 0;
  89. }
  90.  
  91. void agregarValor( Pila *miPila, int valor )
  92. {
  93.    Nodo *nodo;
  94.  
  95.    nodo = (Nodo *)malloc(sizeof(Nodo));
  96.    nodo->num = valor;
  97.    nodo->sig = NULL;
  98.  
  99.    if( estaVacia( miPila ) == 1 )
  100.        miPila->primero = nodo;
  101.    else
  102.        miPila->ultimo->sig = nodo;
  103.    miPila->ultimo = nodo;
  104.  
  105. }
  106.  
  107. void mostrarPila( Pila *miPila )
  108. {
  109.    Nodo *nodo;
  110.  
  111.    for( nodo = miPila->primero; nodo != NULL; nodo = nodo->sig )
  112.        printf("%d\n", nodo->num);
  113. }
  114.  
  115. int borrarTope( Pila *miPila )
  116. {
  117.    Nodo *nodo;
  118.    int valor;
  119.  
  120.    if( miPila->ultimo == miPila->primero )
  121.    {
  122.        valor = miPila->ultimo->num;
  123.        free( miPila->ultimo );
  124.    }
  125.    else
  126.    {
  127.        nodo = miPila->primero;
  128.  
  129.        while( nodo->sig != miPila->ultimo )
  130.            nodo = nodo->sig;
  131.  
  132.        valor = miPila->ultimo->num;
  133.        free( miPila->ultimo );
  134.        miPila->ultimo = nodo;
  135.    }
  136.  
  137.    return valor;
  138. }
  139.  
  140. void borrarTodo( Pila *miPila )
  141. {
  142.    Nodo *nodo;
  143.  
  144.    nodo = miPila->primero->sig;
  145.  
  146.    while( miPila->ultimo != NULL )
  147.    {
  148.        free( miPila->primero );
  149.        miPila->primero = nodo;
  150.        if( nodo != miPila->ultimo )
  151.            nodo = nodo->sig;
  152.    }
  153. }
  154.  
  155.  


En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
xaps

Desconectado Desconectado

Mensajes: 157



Ver Perfil
Re: Problema manejo de Pila
« Respuesta #1 en: 13 Febrero 2014, 00:01 am »

No entiendo que haces en la función borrarTope. Para eliminar el primer elemento de la pila lo único que has de hacer es:
Código:
if(miPila->primero == miPila->ultimo)
{
  free(miPila->primero);
  miPila->primero = NULL;
  miPila->segundo = NULL;
}
else
{
  Nodo* nodo = miPila->primero;
  miPila->primero = miPila->primero->sig;
  free(nodo);
}

En cualquier caso, te recomiendo crear una clase pila y añadirle un parámetro int con el tamaño de la pila, que irías actualizando según añades o eliminas un elemento de la cola.

EDITO: Te añado un enlace hacia un aporte de hace unos meses en el que publiqué las clases pila y cola implementadas por mi. No serán las clases más eficientes que veas, pero te pueden servir para hacerte una idea. Enlace: http://foro.elhacker.net/programacion_cc/aporte_c_clases_pila_y_cola-t405322.0.html;msg1906527#msg1906527


« Última modificación: 13 Febrero 2014, 00:08 am por xaps » En línea

"The programmers of tomorrow are the wizards of the future" - Gave Newel
erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: Problema manejo de Pila
« Respuesta #2 en: 13 Febrero 2014, 00:13 am »

Gracias por el link, me pondre a leerlo, es solo que segun lei, en una pila se extrae el ultimo valor ingresado, y la solucion que me colocaste es para eliminar un elemento de una cola.

EDIT: Es decir mi puntero de nodo lo corro mientras su elemento puntero "sig" sea distinto a la ultima posicion para liberar la ultima posicion y luego hacer esa ultima posicion igual al mi puntero nodo. Pero cuando trato de mostrar despues la pila resultante, me empieza a mostrar valores locos.
« Última modificación: 13 Febrero 2014, 00:17 am por erest0r » En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
xaps

Desconectado Desconectado

Mensajes: 157



Ver Perfil
Re: Problema manejo de Pila
« Respuesta #3 en: 13 Febrero 2014, 00:37 am »

Gracias por el link, me pondre a leerlo, es solo que segun lei, en una pila se extrae el ultimo valor ingresado, y la solucion que me colocaste es para eliminar un elemento de una cola.

EDIT: Es decir mi puntero de nodo lo corro mientras su elemento puntero "sig" sea distinto a la ultima posicion para liberar la ultima posicion y luego hacer esa ultima posicion igual al mi puntero nodo. Pero cuando trato de mostrar despues la pila resultante, me empieza a mostrar valores locos.

El código que te he puesto hace la función POP, que es la que se encarga de eliminar el elemento superior de una pila.
Además, veo distintos errores en varias de las funciones que has programado, como por ejemplo en la función resetPila, que no te encargas de liberar la memoria de los diferentes nodos antes de perder las direcciones de memoria del primer y ultimo nodo. Tampoco te hace falta un puntero hacia el último elemento de la pila, ya que no vas a usarlo para nada (Recordemos que una pila es Last In First Out).
Mírate la clase Stack (Pila) del enlace que te he pasado, yo creo que te ayudará a entender mejor como funcionan las clases pila y cola, y si tienes alguna duda coméntalo y intentaré resolvértela.

Saludos
« Última modificación: 13 Febrero 2014, 00:39 am por xaps » En línea

"The programmers of tomorrow are the wizards of the future" - Gave Newel
erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: Problema manejo de Pila
« Respuesta #4 en: 13 Febrero 2014, 00:46 am »

Bueno, en realidad el puntero "ultimo" de mi pila lo uso para ir enlazando el ultimo nodo agregado hasta ese momento con el nuevo ultimo nodo. Y mi funcion resetPila solo lo uso para el comienzo, simplemente era un inicializador de pila (Sí, debi haberle colocado otro nombre, por la confusion).
En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: Problema manejo de Pila
« Respuesta #5 en: 13 Febrero 2014, 00:51 am »

Logre acomodarlo de forma que ahora si cumple su cometido, aunque buscare maneras mas eficientes de trabajarlo, estas son las 2 funciones que modifique:

Código
  1. int borrarTope( Pila *miPila )
  2. {
  3.    Nodo *nodo;
  4.    int valor;
  5.  
  6.    if( miPila->ultimo == miPila->primero )
  7.    {
  8.        valor = miPila->ultimo->num;
  9.        free( miPila->ultimo );
  10.        miPila->primero = NULL;
  11.        miPila->ultimo = NULL;
  12.    }
  13.    else
  14.    {
  15.        nodo = miPila->primero;
  16.  
  17.        while( nodo->sig != miPila->ultimo )
  18.            nodo = nodo->sig;
  19.  
  20.        valor = miPila->ultimo->num;
  21.        free( miPila->ultimo );
  22.        miPila->ultimo = nodo;
  23.        miPila->ultimo->sig = NULL;
  24.    }
  25.  
  26.    return valor;
  27. }
  28.  
  29. void borrarTodo( Pila *miPila )
  30. {
  31.    while( miPila->primero != NULL )
  32.    {
  33.        Nodo *nodo;
  34.        nodo = miPila->primero;
  35.        miPila->primero = miPila->primero->sig;
  36.        free(nodo);
  37.    }
  38. }
  39.  

De todas maneras, gracias por haberte tomado la molestia  :)
En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
xaps

Desconectado Desconectado

Mensajes: 157



Ver Perfil
Re: Problema manejo de Pila
« Respuesta #6 en: 13 Febrero 2014, 00:56 am »

Logre acomodarlo de forma que ahora si cumple su cometido, aunque buscare maneras mas eficientes de trabajarlo, estas son las 2 funciones que modifique:

Código
  1. int borrarTope( Pila *miPila )
  2. {
  3.    Nodo *nodo;
  4.    int valor;
  5.  
  6.    if( miPila->ultimo == miPila->primero )
  7.    {
  8.        valor = miPila->ultimo->num;
  9.        free( miPila->ultimo );
  10.        miPila->primero = NULL;
  11.        miPila->ultimo = NULL;
  12.    }
  13.    else
  14.    {
  15.        nodo = miPila->primero;
  16.  
  17.        while( nodo->sig != miPila->ultimo )
  18.            nodo = nodo->sig;
  19.  
  20.        valor = miPila->ultimo->num;
  21.        free( miPila->ultimo );
  22.        miPila->ultimo = nodo;
  23.        miPila->ultimo->sig = NULL;
  24.    }
  25.  
  26.    return valor;
  27. }
  28.  
  29. void borrarTodo( Pila *miPila )
  30. {
  31.    while( miPila->primero != NULL )
  32.    {
  33.        Nodo *nodo;
  34.        nodo = miPila->primero;
  35.        miPila->primero = miPila->primero->sig;
  36.        free(nodo);
  37.    }
  38. }
  39.  

De todas maneras, gracias por haberte tomado la molestia  :)

Ahora entiendo por que haces el while en borrarTope, tienes los punteros invertidos. Si inviertes la dirección de los punteros, obtendrás una clase pila mucho más eficiente. Sigo pensando que deberías mirarte el enlace, ya que tienes mal planteada la pila.

Saludos
En línea

"The programmers of tomorrow are the wizards of the future" - Gave Newel
erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: Problema manejo de Pila
« Respuesta #7 en: 13 Febrero 2014, 01:34 am »

En realidad me acabo de dar cuenta que es suficiente un puntero que se ubique en el tope jejeje, gracias por la ayuda, y sobre C++ aun estoy en los comienzos
En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: Problema manejo de Pila
« Respuesta #8 en: 13 Febrero 2014, 01:40 am »

Acabo de modificar mis funciones de modo que solo uso ahora un puntero que se ubica en el tope

Código
  1. void inicializarPila( Pila *miPila )   // Ya no es resetPila ;)
  2. {
  3.    miPila->tope = NULL;
  4. }
  5.  
  6. int estaVacia( Pila *miPila )
  7. {
  8.    if( miPila->tope == NULL )
  9.        return 1;
  10.    else
  11.        return 0;
  12. }
  13.  
  14. void agregarValor( Pila *miPila, int valor )
  15. {
  16.    Nodo *nodo;
  17.  
  18.    nodo = (Nodo *)malloc(sizeof(Nodo));
  19.    nodo->num = valor;
  20.  
  21.    if( estaVacia( miPila ) == 1 )
  22.        nodo->sig = NULL;
  23.    else
  24.        nodo->sig = miPila->tope;
  25.    miPila->tope = nodo;
  26. }
  27.  
  28. void mostrarPila( Pila *miPila )
  29. {
  30.    Nodo *nodo;
  31.  
  32.    for( nodo = miPila->tope; nodo != NULL; nodo = nodo->sig )
  33.        printf("%d\n", nodo->num);
  34. }
  35.  
  36. int borrarTope( Pila *miPila )
  37. {
  38.    Nodo *nodo;
  39.    int valor;
  40.  
  41.    nodo = miPila->tope;
  42.    valor = nodo->num;
  43.  
  44.    miPila->tope = miPila->tope->sig;
  45.    free(nodo);
  46.  
  47.    return valor;
  48. }
  49.  
  50. void borrarTodo( Pila *miPila )
  51. {
  52.    while( miPila->tope != NULL )
  53.    {
  54.        Nodo *nodo;
  55.        nodo = miPila->tope;
  56.        miPila->tope = miPila->tope->sig;
  57.        free(nodo);
  58.    }
  59. }
  60.  
  61.  
  62.  

« Última modificación: 13 Febrero 2014, 01:49 am por erest0r » En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
xaps

Desconectado Desconectado

Mensajes: 157



Ver Perfil
Re: Problema manejo de Pila
« Respuesta #9 en: 13 Febrero 2014, 01:58 am »

En realidad me acabo de dar cuenta que es suficiente un puntero que se ubique en el tope jejeje, gracias por la ayuda, y sobre C++ aun estoy en los comienzos
A eso me refería cuando te decía que no necesitabas un puntero al último elemento.

Por cierto, en C++ se usa delete en vez de free (http://www.cplusplus.com/reference/new/operator%20delete/) y cin/cout para la entrada/salida de datos (http://www.cplusplus.com/doc/tutorial/basic_io/).

También he visto varios system("pause"). Te recomiendo que te leas este post: "|Lo que no hay que hacer en C/C++. Nivel basico|". Enlace: http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html

Saludos
En línea

"The programmers of tomorrow are the wizards of the future" - Gave Newel
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
problema pila cmos pc
Electrónica
smokg 9 9,314 Último mensaje 26 Febrero 2009, 01:12 am
por smokg
Problema con la pila
ASM
B14573R 4 3,764 Último mensaje 12 Diciembre 2009, 10:32 am
por Eternal Idol
problema con pila del bios « 1 2 »
Hardware
Aeros 10 9,008 Último mensaje 11 Julio 2010, 16:46 pm
por simorg
Pila en C++ ¡Problema! Solucionado
Programación C/C++
¡Micronet! 2 8,171 Último mensaje 27 Octubre 2010, 04:46 am
por ¡Micronet!
problema con for en c (eliminar pila)
Programación C/C++
attackers 5 8,648 Último mensaje 5 Noviembre 2011, 16:22 pm
por attackers
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines