Ir ao conteúdo

C Lista duplamente encadeada - c


Ir à solução Resolvido por 1freakday,

Posts recomendados

Postado

Olá, preciso de ajuda em um algoritmo. A pergunta é: implemente um programa com as opções de inserir, buscar, excluir e listar dados usando uma lista duplamente encadeada, com o tema Cidades visitasse pelo vendedor 

 

O algoritmo está praticamente pronto, mas toda vez que rodo, da problema com a opção “liberar lista”. Ele simplesmente não libera e imprime caracteres estranhos Alguém pode ajudar?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct lista2{
    char cidades[51];
    struct lista2* ant;
    struct lista2* prox;
};
typedef struct lista2 Lista2;

Lista2* lst2_cria (void){
    return NULL;
}

Lista2* lst2_insere (Lista2* l, char v[] ){
    Lista2* novo=(Lista2*)malloc(sizeof(Lista2));
    strcpy(novo->cidades, v);
    novo->prox=l;
    novo->ant=NULL;
    if (l!=NULL) l->ant=novo;
    return novo;
}

Lista2* lst2_busca (Lista2*l, char v[]){
    Lista2* p;
    for (p=l; p!=NULL; p=p->prox)
        if (strcmp (p->cidades,v)==0)
            return p;
    return NULL;
}

Lista2* lst2_retira (Lista2* l, char v[]){
    Lista2* p;
    p= lst2_busca(l,v);
    if (p==NULL){
        printf("Cidade nao encontada.\n");
        return l;
    }
    else printf("Cidade retirada.\n");
    if (l==p) l=p->prox;
    else p->ant->prox=p->prox;
    if (p->prox!=NULL)
        p->prox->ant=p->ant;
    free(p);
    return l;
}

int lst2_vazia(Lista2* l){
    if (l==NULL)return 1;
    else return 0;
}

void lst2_imprime (Lista2* l){
    Lista2*p=l;
    if(lst2_vazia(l))
        printf("\n\nA lista esta vazia.\n\n");
    else{
    while(p->prox != NULL)
        p = p->prox;
    while(p != NULL){
        printf("%s\n", p->cidades);
        p = p->ant;
    }
    }
}

void lst2_libera (Lista2* l){
    Lista2* p=l;
    while (p!=NULL) {
        Lista2* t=p->prox;
        free(p);
        p=t;
    }
}

int main()
{
    int n;char cidade[51];
    Lista2* l;
    printf("\n\t\t>-------------------- MENU --------------------<\n\n");
    printf("\n0)Encerrar\n1)Criar lista\n2)Inserir cidade\n3)Retirar cidade\n4)Imprimir lista\n5)Verificar se a lista esta vazia\n6)Liberar lista\n");
    printf("\n\t\t>----------------------------------------------<\n");
    while(1)
    {
        scanf("%d",&n);
        if(n==0)break;
        switch(n)
        {
            case 1:
                l=lst2_cria();
                printf("Lista criada.\n");
                break;
            case 2:
                printf("Digite a cidade que deseja inserir\n");
                scanf(" %[^\n]s", cidade);
                l=lst2_insere(l, cidade);
                break;
            case 3:
                printf("Digite a cidade que deseja retirar\n");
                scanf("%s", cidade);
                l=lst2_retira(l, cidade);
                break;
            case 4:
                lst2_imprime(l);
                break;
            case 5:
                if(lst2_vazia(l))
                    printf("A lista esta vazia.\n");
                else printf("A lista nao esta vazia.\n");
                break;
            case 6:
                lst2_libera(l);
                printf("Lista liberada\n");
                break;
            default:
                printf("\nDigite uma das opções validas.\n");
                break;
        }
    }
    return 0;
}

 

Postado

Bom dia, então você está declarando uma variavel dentro do while, isso pode prejudicar o código, também sempre verifique a ordem lógica:

//troque esse por
while (p!=NULL) {
        Lista2* t=p->prox;
        free(p);
        p=t;
    }

//esse
while(p != NULL){
   free(p);
   p = p->prox;
}

//veja que o loop só começa e continua se p for diferente 
//de NULL

 

Postado

@Luísa Brandão Pois então, tive que rodar o código, e acontece que você precisa liberar os anteriores e depois os proximos, também é preciso retornar a lista na chamada.

 

Lista2* lst2_libera (Lista2* l){
	Lista2 *p = l->ant;
	
	//libera anterior
	while(p != NULL){
		free(p);
		p = p->ant;
	}

	p = l;
	//libera próximo
	while(p != NULL){
		free(p);
		p = p->prox;
	}
    return p;
}

 

Postado

Fiz conforme você disse, mas o problema continuou. Assim, ele roda e tudo, mas quando eu libero a lista aparece a mensagem ''lista liberada'' mas assim que eu imprimo novamente, a lista aparece

Fiz do jeito que voce disse

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct lista2{
    char cidades[51];
    struct lista2* ant;
    struct lista2* prox;
};
typedef struct lista2 Lista2;

Lista2* lst2_cria (void){
    return NULL;
}
Lista2* lst2_insere (Lista2* l, char v[] ){
    Lista2* novo=(Lista2*)malloc(sizeof(Lista2));
    strcpy(novo->cidades, v);
    novo->prox=l;
    novo->ant=NULL;
    if (l!=NULL) l->ant=novo;
    return novo;
}
Lista2* lst2_busca (Lista2*l, char v[]){
    Lista2* p;
    for (p=l; p!=NULL; p=p->prox)
        if (strcmp (p->cidades,v)==0)
            return p;
    
    return NULL;
}


Lista2* lst2_retira (Lista2* l, char v[]){
    Lista2* p;
    p= lst2_busca(l,v);
    if (p==NULL){
        printf("Cidade nao encontada.\n");
        return l;
    }
    else printf("Cidade retirada.\n");
    if (l==p) l=p->prox;
    else p->ant->prox=p->prox;
    if (p->prox!=NULL)
        p->prox->ant=p->ant;
    free(p);
    return l;
    
}
int lst2_vazia(Lista2* l){
    if (l==NULL)return 1;
    else return 0;
}

void lst2_imprime (Lista2* l){
    
    Lista2*p=l;
    
    if(lst2_vazia(l))
        
        printf("\n\nA lista esta vazia.\n\n");
    
    
    else{
        while(p->prox != NULL)
            
            p = p->prox;
        
        
        while(p != NULL){
            
            printf("%s\n", p->cidades);
            
            p = p->ant;
            
        }
        
    }
    
}
Lista2* lst2_libera (Lista2* l){
    Lista2 *p = l->ant;
    
    //libera anterior
    while(p != NULL){
        free(p);
        p = p->ant;
    }
    
    p = l;
    //libera próximo
    while(p != NULL){
        free(p);
        p = p->prox;
    }
    return p;
}

int main()
{
    
    int n;char cidade[51];
    Lista2* l;
    printf("\n\t\t>-------------------- MENU --------------------<\n\n");
    printf("\n0)Encerrar\n1)Criar lista\n2)Inserir cidade\n3)Retirar cidade\n4)Imprimir lista\n5)Verificar se a lista esta vazia\n6)Liberar lista\n");
    printf("\n\t\t>----------------------------------------------<\n");
    while(1)
    {
        
        
        scanf("%d",&n);
        if(n==0)break;
        switch(n)
        {
            case 1:
                
                l=lst2_cria();
                printf("Lista criada.\n");
                break;
            case 2:
                printf("Digite a cidade que deseja inserir\n");
                scanf(" %[^\n]s", cidade);
                l=lst2_insere(l, cidade);
                break;
            case 3:
                printf("Digite a cidade que deseja retirar\n");
                scanf("%s", cidade);
                l=lst2_retira(l, cidade);
                
                break;
                
            case 4:
                
                lst2_imprime(l);
                break;
            case 5:
                if(lst2_vazia(l))
                    printf("A lista esta vazia.\n");
                else printf("A lista nao esta vazia.\n");
                break;
            case 6:
                lst2_libera(l);
                printf("Lista liberada\n");
                break;
            default:
                printf("\nDigite uma das opções validas.\n");
                break;
        }
        
    }
    return 0;
}

 

Postado

Poderia me ajudar mais uma vez? kk essa é a ultima, prometo.

Algoritmo praticamente pronto. Coloquei uma opcao para inserir no inicio e outra no final. Só que quando insiro ambas e vou imprimir invertido, so imprime 2 cidades.

 

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
struct lista2
{
    char cidades[51];
    struct lista2* ant;
    struct lista2* prox;
};
typedef struct lista2 Lista2;

Lista2* lst2_cria (void)
{
    return NULL;
}
Lista2* lst2_insereini (Lista2* l, char v[] )
{
    Lista2* novo=(Lista2*)malloc(sizeof(Lista2));
    strcpy(novo->cidades, v);
    novo->prox=l;
    novo->ant=NULL;
    if (l!=NULL) l->ant=novo;
    return novo;
}
Lista2* lst2_inserefim(Lista2* inicio, char valor[]){

     Lista2* novo, *atual;

     novo = malloc(sizeof(Lista2));
     if(novo == NULL)
         return;
     if(inicio == NULL){
         strcpy(novo->cidades,valor);
         novo->prox = novo->ant = NULL;
         inicio = novo;
     }
     else{
         atual = inicio; /* atual aponta para o início */
         while(atual->prox != NULL) /* enquanto o nó atual não for o último */
            atual = atual->prox;    /* vai para o nó seguinte */
         strcpy(novo->cidades,valor);
         novo->ant = atual;  /*o nó anterior ao novo é o nó atual */
         novo->prox = NULL; /* não há próximo nó, pois o novo será o último */
         atual->prox = novo; /* o nó atual aponta para o novo nó e não é mais o último */
     }
}


Lista2* lst2_busca (Lista2*l, char v[])
{
    Lista2* p;
    for (p=l; p!=NULL; p=p->prox)
        if (strcmp (p->cidades,v)==0)
            return p;

    return NULL;
}
void lst2_buscarcidade(Lista2* l,char v[])
{
    Lista2* p;
    for (p=l; p!=NULL; p=p->prox)
    {
        if (strcmp (p->cidades,v)==0)
        {
            printf("Cidade encontrada\n");
            return;
        }

    }

    printf("Cidade não encontrada\n");
}



Lista2* lst2_retira (Lista2* l, char v[])
{
    Lista2* p;
    p= lst2_busca(l,v);
    if (p==NULL)
    {
        printf("Cidade não encontrada.\n");
        return l;
    }
    else printf("Cidade retirada.\n");
    if (l==p) l=p->prox;
    else p->ant->prox=p->prox;
    if (p->prox!=NULL)
        p->prox->ant=p->ant;
    free(p);
    return l;

}
int lst2_vazia(Lista2* l)
{
    if (l==NULL)return 1;
    else return 0;
}

void lst2_imprimefimini(Lista2* l){
    Lista2*p;
    p=l;
    if (p==NULL){
        printf("\nLista Vazia");
    }
    else{
    while(p!=NULL) {
        printf("%s\n", p->cidades);
        p=p->prox;
    }
    }

}
void lst2_imprimeinifim (Lista2* l)
{

    Lista2*p=l;

    if(lst2_vazia(l))

        printf("\n\nA lista está vazia.\n\n");


    else
    {
        while(p->prox != NULL)

            p = p->prox;


        while(p != NULL)
        {

            printf("%s\n", p->cidades);

            p = p->ant;

        }

    }

}
Lista2* lst2_libera (Lista2* l)
{
    Lista2 *p = l->ant;


    while(p != NULL)
    {
        free(p);
        p = p->ant;
    }

    p = l;

    while(p != NULL)
    {
        free(p);
        p = p->prox;
    }
    return p;
}
void imprimir_menu(){
    printf("\n\t\t>-------------------- MENU --------------------<\n\n");
    printf("\n1)Inserir cidade no fim\n2)Retirar cidade\n3)Buscar cidade\n4)Imprimir lista\n5)Verificar se a lista está vazia\n6)Liberar lista\n7)Encerrar\n8)Inserir cidade no inicio\n0)Mostrar opções\n");
    printf("\n\t\t>----------------------------------------------<\n");
}
int main()
{
    setlocale(LC_ALL, "Portuguese");
    int n,i;
    char cidade[51];
    Lista2* l;
    l=lst2_cria();
    imprimir_menu();
    while(1)
    {


        scanf("%d",&n);
        if(n==7)break;
        switch(n)
        {
        case 0:
            imprimir_menu();
            break;
        case 1:
            printf("Digite a cidade que deseja inserir\n");
            scanf(" %[^\n]s", cidade);
            l=lst2_insereini(l, cidade);
            break;
        case 2:
            printf("Digite a cidade que deseja retirar\n");
            scanf(" %[^\n]s", cidade);
            l=lst2_retira(l, cidade);

            break;
        case 3:
            printf("Digite a cidade que deseja buscar\n");
            scanf(" %[^\n]s", cidade);
            lst2_buscarcidade(l,cidade);
            break;
        case 4:
            printf("De que modo deseja imprimir a lista?\n");
            printf("1)Ordem original\n2)Ordem inversa\n");
            scanf("%d",&i);
            if(i==1)
                lst2_imprimeinifim(l);
            else if(i==2)
                lst2_imprimefimini(l);
            else printf("Digite uma opção válida.\n");
            break;
        case 5:
            if(lst2_vazia(l))
                printf("A lista está vazia.\n");
            else printf("A lista não está vazia.\n");
            break;
        case 6:
            l=lst2_libera(l);
            printf("Lista liberada\n");
            break;
        case 8:
            printf("Digite a cidade que deseja inserir\n");
            scanf(" %[^\n]s", cidade);
            l=lst2_inserefim(l, cidade);
            break;
        default:
            printf("\nDigite uma das opções válidas.\n");
            break;
        }
    }
    return 0;
}

 

adicionado 36 minutos depois

@TYSQUARE89 consegui fazer, pode deixar kkk obrigada

  • Haha 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...