Double lists c ++

1
#include <iostream>

using namespace std;

struct Nodo{
    int nro;
    Nodo *ant;
    Nodo *sgt;

};

void insertarListaFinal(Nodo *&lista, int valor){

    Nodo *q= new Nodo();
    Nodo *t;
    q->nro=valor;
    q->ant=NULL;
    q->sgt=NULL;

    if(lista==NULL){
        lista=q;

    }else{
        t=lista;
        while(t->sgt!=NULL){
            t=t->sgt;
        }
        t->sgt=q;
        q->ant=t;
    }

}


void insertarElementoDespues(Nodo *&lista,int valorBus, int valorIns){

    Nodo *q= new Nodo();
    q->ant=NULL;
    q->sgt=NULL;
    q->nro=valorIns;

    Nodo *p,*a;
    p=lista;

    if(lista!=NULL){
        while(p!=NULL){
            if(p->nro==valorBus){
                a=p->sgt;
                if(p->sgt!=NULL){
                    a->ant=q;
                    p->sgt=a;
                }
                q->ant=p;
                p->sgt=q;
            }
        }
        p=p->sgt;
        }else{
            lista=q;
    }

}
void mostrarListaDoble(Nodo *&lista){

    Nodo *t=lista;
    while(t!=NULL){
        cout<<t->nro<<endl;
        t=t->sgt;
    }

}



int main (){

    Nodo *lista=NULL;

    int n,numero,v1,v2;

    cout<<"Ingrese Cantidad De Numero :";
    cin>>n;

    for(int i=0;i<n;i++){
        cout<<"Numero "<<i+1<<endl;
        cin>>numero;
        insertarListaFinal(lista,numero);
    }

    cout<<"-------------------"<<endl;
    mostrarListaDoble(lista);


    cout<<"Ingrese Valor A Buscar :";
    cin>>v1;
    cout<<"Digite Valor A Insertar :";
    cin>>v2;
    insertarElementoDespues(lista,v1,v2);
    mostrarListaDoble(lista);

    system("pause");
    return 0;
}

He does not show me the list; with the new element that enters the problem is here -

---> 
cout<<"Ingrese Valor A Buscar :";
    cin>>v1;
    cout<<"Digite Valor A Insertar :";
    cin>>v2;
    insertarElementoDespues(lista,v1,v2);
    mostrarListaDoble(lista);
    
asked by Antony Milian 10.10.2018 в 05:06
source

2 answers

1

Nodes are not Lists.

This is a recurring error in StackOverflow in Spanish that generates a lot of confusion.

In the code you have provided you are passing ( Nodo *& ) a reference to pointer to Nodo with the name of lista . And that is as wrong as saying that a step is a ladder, sincerely Do you think the same ?:

The nomenclature is important.

In addition to the incorrect nomenclature of nodes and lists, the rest of your variables are confusing and prone to errors (such as the error you found Zeugirdor ). Avoid using variables whose name is a letter and use names whose meaning is clear in a first reading, names like q , p , t , n , v1 or v2 do not provide any information of its purpose or intentionality, names like nro , sgt and ant are slightly more explanatory but still confusing when context is missing.

Your question is about C ++.

The C ++ language is multi-paradigm, so a priori you are not limited to a specific paradigm; but one of the strengths of the language is its support for the object-oriented programming so I advise you to You really believe a ready object.

Proposal.

Keeping in mind all of the above, your code might look like this:

class Lista // Un objeto lista, nombre auto-explicativo.
{
    struct Nodo
    {
        // Nombres auto-explicativos, valores por defecto.
        int numero      {0};
        Nodo *anterior  {nullptr};
        Nodo *siguiente {nullptr};
    };

    Nodo *raiz {nullptr}; // Nombre auto-explicativo, valor por defecto. 
public:
    void insertarFinal(int valor);
};

Class Lista has an internal class in the private zone that is Nodo ; this private class is inaccessible from the outside favoring the encapsulation : the class itself manages its nodes, from out of the list there is no reason to work with nodes.

With this code, the implementation of insertarFinal might look like:

void insertarFinal(int valor)
{
    if (raiz) // Si hay datos
    {
        Nodo *ultimo = raiz;
        // Avanzamos hasta dar con el último nodo, que será aquel
        // que no tenga siguiente. Nótese el fin de instrucción -----> v
        for (; ultimo && ultimo->siguiente; ultimo = ultimo->siguiente);

        // El siguiente del nuevo Nodo obtiene nullptr por defecto
        // El anterior del nuevo Nodo obtiene el valor de ultimo al construirse
        ultimo->siguiente = new Nodo{valor, ultimo};
    }
    else // Si no hay datos
    {
        // El anterior y siguiente del nuevo Nodo obtienen nullptr por defecto
        raiz = new Nodo{valor};
    }
}

This list could be used like this:

Lista l;
l.insertarFinal(3);
l.insertarFinal(2);
l.insertarFinal(1);

std::cout << l; // Muestra 321

You can see the code working in Wandbox .

    
answered by 10.10.2018 в 14:40
0

This is your "corrected" code:

#include <iostream>

using namespace std;

struct Nodo{
    int nro;
    Nodo *ant;
    Nodo *sgt;

};

void insertarListaFinal(Nodo *lista, int valor){

    Nodo *q= new Nodo;
    Nodo *t;
    q->nro=valor;
    q->ant=NULL;
    q->sgt=NULL;

    if(lista==NULL){
        lista=q;

    }else{
        t=lista;
        while(t->sgt!=NULL){
            t=t->sgt;
        }
        t->sgt=q;
        q->ant=t;
    }

}


void insertarElementoDespues(Nodo *lista,int valorBus, int valorIns){
    Nodo *q= new Nodo;
    q->ant=NULL;
    q->sgt=NULL;
    q->nro=valorIns;

    if(lista!=NULL){
        Nodo *p,*a;
        p=lista;
        while(p!=NULL){
            if(p->nro==valorBus){
                a=p->sgt;
                if(p->sgt!=NULL){
                    a->ant=q;
                    q->sgt=a;
                }
                q->ant=p;
                p->sgt=q;
            }
            p=p->sgt;
        }
    }
    else{
        lista=q;
    }
}

void mostrarListaDoble(Nodo *lista){

    Nodo *t=lista;
    while(t!=NULL){
        cout<<t->nro<<endl;
        t=t->sgt;
    }

}



int main (){

    Nodo *lista=new Nodo;

    int n,numero,v1,v2;

    cout<<"Ingrese Cantidad De Numero :";
    cin>>n;
    if(n>0){
        cout<<"Numero "<<1<<endl;
        cin>>numero;
        lista->nro=numero;
        lista->ant=NULL;
        lista->sgt=NULL;

        if(n>1){
            for(int i=1;i<n;i++){
                cout<<"Numero "<<i+1<<endl;
                cin>>numero;
                insertarListaFinal(lista,numero);
            }
        }
        cout<<"-------------------"<<endl;
        mostrarListaDoble(lista);


        cout<<"Ingrese Valor A Buscar :";
        cin>>v1;
        cout<<"Digite Valor A Insertar :";
        cin>>v2;
        insertarElementoDespues(lista,v1,v2);
        mostrarListaDoble(lista);

    }
    system("pause");
    return 0;
}

What did I do?

Well, first, what I do is to reserve the memory for the list already creating the first node, the "head", if the user enters a n greater than or equal to 1, I necessarily assign the values of the head in main and then change to for to be greater than 1.

Then I also fixed a problem in insertarElementoDespues since you had put:

        if(p->sgt!=NULL){
            a->ant=q;
            p->sgt=a;
        }

And it's really:

        if(p->sgt!=NULL){
            a->ant=q;
            q->sgt=a;
        }

Since the next pointer of p is a , and as if you assign it back to does not make sense, you have to assign that the next pointer of q is a , not p .

I also changed all *& by directly * , since you are working with pointers and I changed the Nodo(); for Nodo since what you do is create a structure of type Nodo is not a function Nodo .

I also added some checks, like not to run if n is 0 or things like that, I invite you to review it so you can see what I changed and if you have doubts about any part, ask me!

I hope it serves you!

    
answered by 10.10.2018 в 05:48