Circular list doubly linked

1

This code tries to implement a double linked circular list

The code compiles, does not throw an error, but gets stuck when trying to enter numbers

#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;
    }else{
        while (P->sig!=CAB){
            P=P->sig;
    }
    } 
        P->sig=AUX;
        AUX->ant=P;
        CAB->ant=AUX;
}

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(Q);
        }
    }
    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(Q);
        }
    }
    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();
}

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

2 answers

0

The code had several logical errors, other variables, etc. Here it appears to work without problems

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

void clrscr();

//ESTO ES PARA CREAR LA LISTA
struct lista
{
    int info;
    struct lista *sig,*ant;
}*CAB=NULL,*AUX=NULL,*P=NULL,*FD=NULL,*QD=NULL,*Fd=NULL,*Qd=NULL;

int main()
{
    void insertard(void);
    void extraerd(void);
    void visualizard(void);
    void visualizari(void);
    void eliminardespues();
    void eliminarantes();

    char opc;
    do{
        clrscr();
        printf("____________________________________________________\n");
        printf("|_???MENU DE LISTA CIRCULAR DOBLEMENTE ENLAZADA!!!__|\n");
        printf("|___________________________________________________|\n");
        printf("|___________________________________________________|\n");
        printf("|___________SELECCIONE UNA OPCION___________________|\n");
        printf("|___________________________________________________|\n");
        printf("|___________________________________________________|\n");
        printf("|_________1) INSERTAR_______________________________|\n");
        printf("|_________2) VISUALIZAR ASCENDENTE__________________|\n");
        printf("|_________3) VISUALIZAR DESCENDENTE_________________|\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; /* primera ejecuci?n de este m?todo P = NULL */
    AUX=(struct lista *)malloc(sizeof(struct lista));
    clrscr();
    printf("INGRESE UN NUMERO ENTERO: ");
    scanf("%d",&AUX->info);
    AUX->sig=CAB; //El puntero al siguiente nodo sea nulo (CAB es nulo)
    AUX->ant=CAB; //El puntero al anterior nodo sea nulo (CAB es nulo)
    if(CAB==NULL){ //Pregunto si CAB es igual igual a Nulo
        CAB=AUX;
        P=AUX;/*La primera ejecución de este método P ya no es NULL pero P está apuntando a AUX */
    }else{ //ESTO SI
        while(P->sig!=CAB){
            P=P->sig;
        }
    }
    P->sig=AUX; //El puntero siguiente de P toma el valor de AUX
    AUX->ant=P;
    CAB->ant=AUX;
}

void eliminardespues(){
    int x;
    clrscr();
    printf("INGRESE UN NUMERO PARA ELIMINAR EL SIGUIENTE: ");
    scanf("%d",&x);

    FD=CAB;
    QD=CAB;
    while(FD->info!=x&&FD->sig!=CAB){ //si lo que voy a eliminar es distinto al n?mero que me ingresaron y si hay otro
        FD=FD->sig; //paso al siguiente nodo
    }
    QD=FD->sig;
    if(FD->sig==CAB&&FD->info==x){
        printf("\nES LA CABECERA! NO SE PUEDE ELIMINAR");
    }else
       if(FD->sig==CAB&&FD->info!=x){
        printf("\nEL NUMERO INGRESADO NO SE ENCUENTRA EN LA LISTA");
    }else{
           FD->sig=QD->sig;
           (QD->sig)->ant=FD;
           printf("\nELIMINADO %d",QD->info);
           free(QD); //liberar el espacio en memoeria ocupado por QD
       }
       getch();
}

void eliminarantes()
{
    int xd;
    clrscr();
    printf("INGRESE UN NUMERO PARA ELIMINAR EL ANTERIOR: ");
    scanf("%d",&xd);

    Fd=CAB;
    Qd=CAB;
    while(Fd->info!=xd){
        Fd=Fd->ant;
    } Qd=Fd->ant;

    if(Fd==CAB){
        printf("\nES LA CABECERA! NO SE PUEDE ELIMINAR");
    }else{
        if(Qd==CAB){
            CAB=CAB->sig;
            Fd->ant=Qd->ant;
            (Fd->ant)->sig=Fd;
            printf("\nELIMINADO %d",Qd->info);
        }else{
            Fd->ant=Qd->ant;
            (Qd->ant)->sig=Fd;
            printf("\nELIMINADO %d",Qd->info);
        }
        free(Qd);
    }
    getch();
}

void visualizard(void)
{
    clrscr();
    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();
}

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

void clrscr()
{
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD coord = {0, 0};
    DWORD count;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(hStdOut, &csbi);
    FillConsoleOutputCharacter(hStdOut, ' ', csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
    SetConsoleCursorPosition(hStdOut, coord);
}
    
answered by 28.10.2017 / 21:41
source
1

When starting the program P is initialized to 0:

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

And yet at the time of inserting the first item in the list you do this:

    P->sig=AUX;

P does not point to a valid memory address. Consequently P->sig neither. The Operating System does not usually like too much that a program writes in memory that it does not correspond to it because it tends to corrupt the memory of other processes ... so when detecting that access, it heals in health and kills your program.

The solution is to implement the double-linked list correctly. This is: you only need a pointer to the first item in the list:

struct lista
{
    int info;
    struct lista *sig,*ant;
} * raiz = NULL; // Intenta no usar variables globales

To insert an element, simply add it to the end of this pointer:

void insertard(void)
{
    // prefiero calloc porsque incializa todos los bytes a 0
    struct lista* nuevo = (struct lista *)calloc(1,sizeof(struct lista));

    system("cls");
    printf("INGRESE UN NUMERO ENTERO:");
    scanf("%d",&nuevo->info);

    if( raiz == NULL ) // Si es el primer elemento de la lista
    {
      nuevo->sig = nuevo;
      nuevo->ant = nuevo;
      raiz = nuevo;
    }
    else // En caso contrario, añadimos el nodo al final de la lista
    {
      struct lista* ultimo = raiz->ant;
      ultimo->sig = nuevo;
      nuevo->ant = ultimo;

      nuevo->sig = raiz;
      raiz->ant = nuevo;
    }
}

And that's it ... no more pointers are needed. If that, as a help, you can use a pointer that points to the last one in the list ... it will simplify the necessary code to add elements at the end (you will not have to iterate the list every time) and go through the list in reverse order but it will complicate you in the sense that you will have to manage two pointers ... this part of your account runs.

    
answered by 04.10.2017 в 19:24