Read the next item in the list

0

I have this program that does not throw an error, but the visualization procedure only shows the first item in the list. How do I continue printing the following list items?

#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>

struct lista
{
    int info;
    struct lista *sig,*ant;
}*CAB=NULL,*AUX=NULL,*Q=NULL,*P=NULL,*F=NULL,*QD=NULL,*FD=NULL;

int main() {
    void insertard(void);
    void extraerd(void);
    void visualizard(void);
    void visualizari(void);
    void eliminardespues();
    void eliminarantes();
    char opc;
    do{
        system("cls");
        printf("___________________________________________________\n");
        printf("_¡¡¡MENU DE LISTA CIRCULAR DOBLEMENTE ENLAZADA!!!__\n");
        printf("___________________________________________________\n");
        printf("____________SELECCIONE UNA OPCION__________________\n");
        printf("___________________________________________________\n");
        printf("___________________________________________________\n");
        printf("__________1) INSERTAR______________________________\n");
        printf("__________2) VISUALIZAR ASCENDIENTE________________\n");
        printf("__________3) VISUALIZAR DESCENDIENTE_______________\n");
        printf("__________4) INGRESAR Y ELIMINAR SIGUIENTE_________\n");
        printf("__________5) INGRESAR Y ELIMINAR ANTERIOR__________\n");
        printf("__________6) SALIR_________________________________\n");
        printf("___________________________________________________\n");
        opc=getch();
        switch(opc)
        {
        case '1':
            insertard();
            break;
        case '2':
            visualizard();
            break;
        case '3':
            visualizari();
            break;
        case '4':
            eliminardespues();
            break;
        case '5':
            eliminarantes();
            break;
        }
    } while(opc!='6');
    getch();
    return 0;
}

void insertard(void)
{
    P=CAB;
    AUX=(struct lista *)malloc(sizeof(struct lista));
    system("cls");
    printf("INGRESE UN NUMERO ENTERO: ");
    scanf("%d",&AUX->info);
    AUX->sig=CAB;
    AUX->ant=CAB;
    F=AUX;
    if(CAB==NULL){
        CAB=AUX;
        P=AUX;
    }else{
        while (P->sig!=CAB){
            P=P->sig;
    }
    }
        P->sig=AUX;
        AUX->ant=P;
        AUX->sig=CAB;
}
void eliminardespues(){
    int x;
    system("cls");
    printf("INGRESE UN NUMERO PARA ELIMINAR EL SIGUIENTE: ");
    scanf("%d",&x);

    FD=CAB;
    QD=CAB;
    while(FD->info!=x&&FD->sig!=CAB){
    FD=FD->sig;
    }QD=FD->sig;

    if(FD->sig==CAB&&FD->info!=x){
        printf("\nEL NUMERO INGRESADO NO SE ENCUENTA EN LA LISTA");
    }else{
        if(FD->info==x){
            FD->sig=QD->sig;
            (QD->sig)->ant=FD;
            printf("\nELIMINADO %d",QD->info);
            free(QD);
        }
    }
    getch();
}

void eliminarantes()
{
    int x;
    system("cls");
    printf("INGRESE UN NUMERO PARA ELIMINAR EL ANTERIOR");
    scanf("%d",&x);

    FD=CAB;
    QD=CAB;
    while (FD->info!=x&&FD->sig!=CAB){
        FD=FD->sig;
    }QD=FD->ant;
    if(FD->sig==CAB&&FD->info!=x){
        printf("\nEL NUMERO INGRESADO NO SE ENCUENTA EN LA LISTA");
    }else{
        if(FD->info==x){
            FD->ant=QD->ant;
            (QD->ant)->sig=FD;
            printf("\nELIMINADO %d",QD->info);
            free(QD);
        }
    }
    getch();
}

void visualizard(void)
{
    system("cls");
    if(CAB==NULL){
        printf("LISTA VACIA");
        getchar();
        return;
    }
    AUX=CAB;
    printf("LISTA:\n\n");
    while(AUX->sig!=CAB){
        printf("-> %d\n",AUX->info);
        AUX=AUX->sig;
    }
    if(AUX->sig==CAB){
        printf("-> %d\n",AUX->info);
    }
    getch();
}

This function fails:

void visualizari(void){
    system("cls");
    if(F==NULL){
        printf("LISTA VACIA");
        getchar();
        return;
    }
    AUX=F;
    printf("LISTA:\n\n");
    do{
        printf("-> %d\n",AUX->info);
        AUX=AUX->ant;
    }while(AUX->sig!=CAB);
    getch();
}
    
asked by Alejandro Caro 05.10.2017 в 22:08
source

1 answer

2

Your program does not work. You insist (and I do not understand the reason) in following practices that are leading you down the path of bitterness:

  • Global variables: Do not use them . You do not need to resort to them. Under its docile and simple appearance hide a lot of complicated mistakes to understand and detect.

  • Use your variables: You can give the variables the name you want ... why do you choose cryptic names? Why do you use so many variables? A double linked list only needs to operate a single pointer to one of the nodes. Then, for several operations, let's say a couple more, these being local). That gives 3 pointers, while your program is using 7 and all global .

Being global their value will depend on what you have done in previous operations. Are you sure that the values of the pointers are valid regardless of the sequence of operations you perform?

Let's see it in perspective: Imagine that to be able to live you had to manually contract the heart muscle (controlling both the rhythm and the pressure you make in each pump to not faint and not cause embolism due to excess pressure) and the same for breathing. Also imagine that you have to take care of moving the muscles of your stomach to make digestion and so that the intestines can move the food boluses ... the resulting system would not allow you to sleep or think about anything other than keeping you alive ... the system is not viable and the same thing is happening to you.

Your program does not reach, or should not, get to visualize data because it fails to insert a second element. Why? Various reasons:

void insertard(void)
{
    P=CAB; // 2
    AUX=(struct lista *)malloc(sizeof(struct lista));
    system("cls");
    printf("INGRESE UN NUMERO ENTERO:");
    scanf("%d",&AUX->info);
    AUX->sig=CAB; // 1,3
    AUX->ant=CAB; // 1,3
    F=AUX;
    if(CAB==NULL){
        CAB=AUX;
        P=AUX; // 2
    }else{
        while (P->sig!=CAB){ // 3
            P=P->sig;
    }
        P->sig=AUX; // 2
        AUX->ant=P; // 2
        AUX->sig=CAB;
    }
}
  • An misplaced assignment that does not make sense. This sounds like ... " I have no idea where I'm going to place the node but I'm going to do something because they ask me to ". If something is not necessary, do not do it . In this case you would already have pointers initialized ... how would you detect after the pointers point to where they should? they are already initialized, then to distinguish between a good and a bad element you have to compare memory addresses

  • What does P look like in all this? P does not make any sense in an empty list but you insist on using it and this has consequences ...

  • We get to the jackpot: You insert the first element, even though it is supposed to be a circular list, it turns out that the pointers sig and ant point to 0 (note that CAB does not yet point to the new node) ... then you insert a second element, so P points to the header node and when you reach while ... surprise !!! P->sig == 0 != CAB , then you jump to the null pointer and from there the party broke down.

  • The error is a sum of the 3 commented points and is already teaching you that the list is poorly constructed. And, I insist, you have pointers:

    • Except CAB all should be pointers defined in the functions (and only if necessary)
    • To insert an element to the end of a circular list (note that being circular is infinite because you never reach the end), just do:

      ultimoNodo = CAB->ant;
      

      And it's something that makes all the sense in the world ... if you have a list in which the sig pointers follow a path such that

      A -> B -> C -> A
      

      then pointers ant make the following route:

      A <- B <- C <- A
      

      Well, to find the last node (in this case C ), we can go through the whole list using sig ( A -> B -> C ) that implies a loop and, in this case, three jumps ... or we can use the pointer ant ( C <- A ), which always implies a jump and does not force to keep rare pointers in the application.

    Now, assuming that, by mysteries of life, your program does not fail at this point, we come to the function you mention and find that (assuming that the pointer P is correctly assigned) the loop check is not correct: while(AUX->sig != CAB) . If you are in the last node of the circular list ... Where does AUX->sig point? Exactly, to the first node of the list, CAB ... and there your loop dies. The check should be while(AUX!=CAB) .

    On the other hand, I insist, your code is too complex for what you have to do ... and to show a button:

    void visualizari(void){
      system("cls");
      if(F==NULL){
        printf("LISTA VACIA");
      }
      else
      {
        printf("LISTA:\n\n");
        AUX = CAB->ant; // vamos al ultimo elemento
        do{
          printf("-> %d\n",AUX->info);
          AUX=AUX->ant;
        }while(AUX!=CAB);
      }
      getch();
    }
    

    Notice how the pointer P is not necessary at all (one less concern in your program)

        
    answered by 06.10.2017 в 14:02