Hola!

Registrándote como bakuno podrás publicar, compartir y comunicarte en privado con otros bakuos :D

Regístrame ya!

programadores en c++, necesito de su ayuda

DemiDante

Bovino Milenario
Desde
23 Dic 2008
Mensajes
1.000
:histerica: pues miren la cosa esta de esta menera, anteriormente aqui en el foro algunos de ustedes me habian echado la mano con un programa de listas enlazadas de doble recorrido y me fue muy util todos los consejos y sugerencias que me dieron pero ahora ese mismo programa le tengo que anexar otra parte mas que seria la parte de listas circular es decir que el ultimo nodo apunte al inicio de lista, hacer un recorrido y una impresion, mas o menos se que es lo que tengo que hacer pero no estoy muy seguro de eso por tal razon necesito de su ayuda otra vez, de echo aki esta el codigo y pues le falta esa parte que les menciono

HTML:
#include <stdio.h>
#include <Iostream.h>
#include <conio.h>

struct NODO{
       int DATO;
       struct NODO* sig;
       struct NODO* ant;
};

struct NODO* InicioLista=NULL,* Recorre=NULL,* AUX=NULL,* FinLista=NULL;

void InsertaNodo(int Elemento){
     AUX=new (struct NODO);
     AUX->DATO=Elemento;
     AUX->sig=NULL;
     AUX->ant=NULL;

     if (InicioLista==NULL){
     InicioLista=AUX;
    }
      else {
             Recorre=InicioLista;
             while(Recorre->sig != NULL){
             Recorre=Recorre->sig;
              }
                Recorre->sig=AUX;
                AUX->ant=Recorre;
                FinLista=AUX;
              }
            }

void ImprimirLista( ){
     Recorre=InicioLista;
     while(Recorre!=NULL){
     cout<<Recorre->DATO<<" ";
     Recorre=Recorre->sig;
     }
     getch();
   }

void ImprimirListaAlreves( ){
      Recorre=FinLista;
      while(Recorre!=NULL){
      cout<<Recorre->DATO<<" ";
      Recorre=Recorre->ant;
    }
    getch();
   }

void main( ){
     int opc, Elemento;
     do{
          cout<<"1)Insertar\n";
          cout<<"2)ImprimirLista\n";
          cout<<"3)ImprimirLista Al reves\n";
          cout<<"4)Salir\n";
          cout<<"Opcion : ";
          cin>>opc;

              if (opc==1){
              cout<<"Elemento";
              cin>>Elemento;
              InsertaNodo(Elemento);
          }
          else if (opc==2){
          cout<<"Elemento de la lista .... \n";
          ImprimirLista( );
     }
     else if (opc==3){
     cout<<"Elemento de la lista .... \n";
     ImprimirListaAlreves();
     }
    }  while(opc!=4);

  }
les estare agradecido y espero que me puedan ayudar. Saludos
 
Es muy fácil, y sencillo.

Una lista termina donde el nodo, tiene en el puntero que apunta al siguiente nodo, el valor "null", por lo tanto, lo único que necesitas haces, es, cuando ya tengas la cabezera (el primer nodo de la lista), lo pasas como argumento en una función que vas a crear, y esa función toma el parámetro, y recorre la lista, hasta llegar al último nodo "el que tiene en el puntero al siguiente elemento el valor NULL", entonces, sólo le cambias NULL por el puntero que le pasaste como argumento, y listo.

Ejemplo:

function hacerCircular(Lista * laLista) {
Lista * primerElemento = laLista;
Lista * ListaCompletaCircular = laLista;
while(ListaCompleta != NULL) {
if(ListaCompleta->siguienteElemento == NULL) {
ListaCompleta->siguienteElemento = primerElemento;
}
return ListaCompletaCircular;
}

La verdad no te recomiendo que sigas preguntando por estas cosas, ya que, desarrollas tu lógica si tú mismo lo resuelves.

Saludos!
 
Las modificaciones que tienes que hacer son bastante fáciles puesto que ya tienes creada una lista vinculada. La diferencia es que ahora el ultimo nodo en tu estructura; envés de que su puntero <code>sig</code> sea <code>null</code>, tiene que apuntar hacia el primer nodo de la lista. (Por eso se le llama "lista circular" porque una vez que llegas al último nodo, el siguiente nodo viene a ser el primero). Igual con el <code>ant</code> del primer nodo, enves de ser <code>null</code> tiene que apuntar al ultimo nodo de tu lista para completar el circulo.

También tienes que modificar la lógica de tus métodos/funciones. Porque, por ejemplo, ya no puedes decir que para encontrar el ultimo nodo solo tienes que buscar el nodo cuyo <code>sig</code> sea <code>null</code>, esto ya no nos serviría porque todos los nodos (incluso el ultimo) apuntan hacia algun otro nodo. Lo mismo ocurre si quieres encontrar el primer nodo de tu lista, (ya no vale decir que su <code>ant</code> es <code>null</code>).

Como dijo alguien, es un buen ejercicio mental que le encuentres tú mismo la lógica a cada uno de los métodos mientras aun estés viendo estructuras básicas. Si no los siguientes cursos se te pueden complicar. Cualquier duda que tengas háznosla saber.
 
Las modificaciones que tienes que hacer son bastante fáciles puesto que ya tienes creada una lista vinculada. La diferencia es que ahora el ultimo nodo en tu estructura; envés de que su puntero <code>sig</code> sea <code>null</code>, tiene que apuntar hacia el primer nodo de la lista. (Por eso se le llama "lista circular" porque una vez que llegas al último nodo, el siguiente nodo viene a ser el primero). Igual con el <code>ant</code> del primer nodo, enves de ser <code>null</code> tiene que apuntar al ultimo nodo de tu lista para completar el circulo.

También tienes que modificar la lógica de tus métodos/funciones. Porque, por ejemplo, ya no puedes decir que para encontrar el ultimo nodo solo tienes que buscar el nodo cuyo <code>sig</code> sea <code>null</code>, esto ya no nos serviría porque todos los nodos (incluso el ultimo) apuntan hacia algun otro nodo. Lo mismo ocurre si quieres encontrar el primer nodo de tu lista, (ya no vale decir que su <code>ant</code> es <code>null</code>).

Como dijo alguien, es un buen ejercicio mental que le encuentres tú mismo la lógica a cada uno de los métodos mientras aun estés viendo estructuras básicas. Si no los siguientes cursos se te pueden complicar. Cualquier duda que tengas háznosla saber.
.

Para saber donde está el principio de su anterior lista, puede guardar el puntero de inicio en otro puntero y el de la cola igual.
 
Así es. De hecho creo que ni le hace falta el puntero de la cola, ya que la cola puede ser identificada cuando sig == InicioLista. O para ir directo a la cola puede usar ant de InicioLista. Aun así tiene que eliminar todos los null's de sus sig's y ant's para que pueda ser considerada una lista circular. Y como lo mencione antes, sus métodos necesitaran nueva lógica ya que no pueden estar buscando casos en que ocurran NULL's porque simplemente no los van a haber en una lista circular (con la excepción claro de que la lista este vacía, otra cosa que tomar en cuenta para los métodos).
 
Mi amigo recuerda que en especial en estas estructuras de datos no debes perder nunca tus apuntadores por que seria un error muy grave. En las listas circulares doblemente ligadas necesitas que cada nodo tenga 2 apuntadores hacia atras y hacia adelante. El ultimo nodo de la lista en su apuntador siguiente se dirige al primero y el primer nodo en su apuntador anterior se dirige al ultimo cierto.

Recuerda que en las listas simples se tenia un apuntador principal llamado raiz que apuntaba al primer nodo de la lista, al nodo raiz. Esto hace que sepas cual es el inicio de tu lista.

Para este caso de listas circulares teoricamente se pierde el concepto de raiz. Pero aun asi podrias poner un apuntador a tu nodo inicial y siempre verificar si el nodo en el que te encuentras esta apuntando en su parte siguiente hacia donde mismo que apunta tu otro apuntador del nodo inicial, con esto podrias ver si estas en el ultimo nodo de la lista y evitas que se cicle infinitamente. No se si me explico jeje es algo confuzo.

Dime si me di antender y si no pues tratare de realizar un diagrama y enviartelo va. Espero que no te sea tan complicado, suerte compañero!
 
Así es. De hecho creo que ni le hace falta el puntero de la cola, ya que la cola puede ser identificada cuando sig == InicioLista. O para ir directo a la cola puede usar ant de InicioLista. Aun así tiene que eliminar todos los null's de sus sig's y ant's para que pueda ser considerada una lista circular. Y como lo mencione antes, sus métodos necesitaran nueva lógica ya que no pueden estar buscando casos en que ocurran NULL's porque simplemente no los van a haber en una lista circular (con la excepción claro de que la lista este vacía, otra cosa que tomar en cuenta para los métodos).

Exácto!, así es... :P
 
Ta facil, imaginate un anillo de acero, entonces por un punto arbitrario lo tomas con los dedos, tus dedos son un puntero hacia un inicio y fin al mismo tiempo, si cambias el dedo de posicion se cumple la misma regla, osea, tienes un nodo vacio, el cual apuntara al primer nodo, y al valor anterior no sirve de nada en este nodo vacio, ya que solo es la referencia, es el punto de entrada, entonces, para moverte en la estructura, te mueves siempre uno hacia adelante desde el nodo vacio, sabras que el primer elemento esta en siguiente del nodo vacio y podras moverte atras o adelante en el primer nodo de manera que normalmente lo haces, como saber si estas en el prier nodo??? sencillo si el siguiente del nodo vacio es igual al nodo actual, por lo demas es cuestion de visualizacion.
 
El tema dice c++, ahi estás aplicando algo que mas bien tinte de código estructurado de C (aunque uses instrucciones de c++). Te recomendaria trasladar la lógica utilizando objetos. (por ejemplo tu tipo nodo podria ser definido como una clase).

Saludos
 
El tema dice c++, ahi estás aplicando algo que mas bien tinte de código estructurado de C (aunque uses instrucciones de c++). Te recomendaria trasladar la lógica utilizando objetos. (por ejemplo tu tipo nodo podria ser definido como una clase).

Saludos

Tambein note eso, pero aun asi es considerado C++ porque C no permite que struct's contengan funciones/metodos. Pero estas en lo cierto, seria mejor usar class en lugar de struct.

EDIT: Hmm, acabo de notar que sus funciones nisiquiera son declaradas como miembros de su struct, realmente esta usando C puro! (con excepccion de los cin/cout claro)
 
Volver
Arriba