parte 5 – gestão dinâmica de memória (lista ligada)

Principal vantagem de se usar lista ligada: flexibilidade

O acesso é sequencial, em que cada estrutura contém: os campos e um ponteiro para o próximo elemento da lista
operações com listas ligadas:
1) criar a lista
2) verificar se está vazia
3) pesquisar/lustar
4) adicionar um elemento
5) retirar um elemento
6) destruir a lista

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TAM 100


typedef struct objeto livro, *plivro;

struct objeto{
    char titulo[TAM], autor[TAM];
    int cota;
    plivro prox; //ponteiro para o proximo elemento da lista
};


//
int lista_vazia(plivro p);
plivro insere_inicio(plivro p);
plivro insere_final(plivro p);
plivro insere_ordenado(plivro p);
void mostra(plivro p);
plivro elimina(plivro p);
void destruir(plivro p);
plivro ler_ficheiro(plivro p);
void guarda_ficheiro(plivro p);

//2) verificar se está vazia
int lista_vazia(plivro p){
    if(p==NULL){
        return 1;
    }else{
        return 0;
    }
}

int menu(){
    int i;
    puts("1 - adiciona livro - inicio");
    puts("2 - adiciona livro - final");
    puts("3 - adiciona livro - ordenado");
    puts("4 - elimina livro");
    puts("5 - lista livros");
    puts("6 - esvaziar a lista");
    puts("7 - carregar lista de um ficheiro");
    puts("8 - terminar");
    puts("Escolha uma opcao: ");
    
    do{
        scanf(" %d", &i);
    }while(i <0 || i >8);
    
    return i;
}

plivro insere_inicio(plivro p){
    plivro novo;
    novo = malloc(sizeof(livro)); //aponta para um qq espaço em memória
    
    if(novo == NULL){
        printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio");
        return p;
    }else{
        printf("Titulo: ");
        scanf(" %99[^\n]", novo->titulo);
        printf("Autor: ");
        scanf(" %99[^\n]", novo->autor);
        printf("Cota: ");
        scanf("%d", &novo->cota);
               
        //surge agora uma parelha obrigatória
        novo->prox=p; //aponto o novo para a primeira posição
        p=novo; //a primeira posição é o novo
                
        return p;
    }
    free(novo);
}

plivro insere_final(plivro p){
    plivro novo, aux;
    novo = malloc(sizeof(livro)); //aponta para um espaço em memoria
    if(novo == NULL){
        printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio");
        return p;
    }else{
        printf("Titulo: ");
        scanf(" %99[^\n]", novo->titulo);
        printf("Autor: ");
        scanf(" %99[^\n]", novo->autor);
        printf("Cota: ");
        scanf("%d", &novo->cota);
        novo->prox=NULL;
        
        //se estiver vazio, insere no inicio
        if(p == NULL){
            p = novo;
        }else{
        //se já tiver pelo menos um elemento
            aux=p;
            while(aux->prox != NULL){
                aux = aux->prox;
            }
            aux->prox = novo;
        }
        return p;
    }
    free(novo);
}

plivro insere_ordenado(plivro p){
     plivro novo, aux;
    novo = malloc(sizeof(livro)); //aponta para um espaço em memoria
    if(novo == NULL){
        printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio");
        return p;
    }else{
        printf("Titulo: ");
        scanf(" %99[^\n]", novo->titulo);
        printf("Autor: ");
        scanf(" %99[^\n]", novo->autor);
        printf("Cota: ");
        scanf("%d", &novo->cota);
        novo->prox=NULL;
        
        //se estiver vazio
        if(p == NULL || strcmp(novo->titulo, p->titulo) < 0){
        //if(p == NULL || novo->cota < p->cota){
            novo->prox = p;
            p = novo;
        }else{
        //se já tiver pelo menos um elemento
            aux=p;
             while(aux->prox != NULL && strcmp(novo->titulo, aux->titulo) >0){
             //while(aux->prox != NULL && novo->cota > aux->cota){
                aux = aux->prox;
            }
            novo->prox = aux->prox;
            aux->prox = novo;
        }
        return p;
    }
    
    free(novo);

}


void mostra(plivro p){
    
    if(p==NULL){
        printf("\nerro: lista vazia, sem elementos para listar!\n\n");
    }else{
    while(p!=NULL){
        printf("%s\t%s\t%d\n", p->titulo, p->autor, p->cota);
        p = p->prox;
    }
    }
}


plivro elimina(plivro p){
    int apaga;
    plivro atual, anterior=NULL;
    
    atual= p;
    
    if(p==NULL){
        printf("\nerro: lista vazia sem informacao\n");
        return p;
    }else{
        mostra(p);
        printf("qual o livro e cota que pretende eliminar?");
        scanf("%d", &apaga);
        while(atual!=NULL && atual->cota != apaga){
            anterior = atual;
            atual = atual->prox;
        }
        if(anterior ==NULL){
            p = atual->prox;
        }else{
            anterior->prox = atual->prox;
        }
    free(atual);
    return p;
    }
}

void destruir(plivro p){
    plivro aux;
    
    if(p==NULL){
        printf("\nerro: nada para apagar!\n");
    }
    
    while(p!=NULL){
        aux = p;
        p=p->prox;
        free(aux);
    }

}

plivro ler_ficheiro(plivro p){
    FILE *f;
    plivro novo=NULL;
        
    if(p!=NULL){
        printf("\nerro: lista ja preenchida\n");
        return p;
    }else{
    
    f = fopen("listaLivros.dat", "rb");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return p;
    }else{
       
       while(feof(f) == 0){
            novo = malloc(sizeof(livro));
            fread(novo, sizeof(livro), 1, f);
            novo->prox = p;
            p = novo; //erro aqui
        }
    }
    }
    free(novo);
    fclose(f);
    return p;
}

void guarda_ficheiro(plivro p){
    FILE *f;
    
    f = fopen("listaLivros.dat", "wb");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return;
    }else{
        while(p != NULL){
        fwrite(p, sizeof(livro), 1, f);
        p=p->prox;
        }
        fclose(f);
        free(p);
    }
}


int main() {
    int escolha;
    plivro lista = NULL; //1) criar a lista
    
    if(lista_vazia(lista)==1){
    do{
        escolha = menu();
        switch(escolha){
            case 1: lista = insere_inicio(lista); break;
            case 2: lista = insere_final(lista); break;
            case 3: lista = insere_ordenado(lista); break;
            case 4: lista = elimina(lista); break;
            case 5: mostra(lista); break;
            case 6: destruir(lista); break;
            case 7: lista= ler_ficheiro(lista); break;
        }
    
    }while(escolha != 8);
    }else{
        printf("nao foi possivel inicializar!");
    }

    guarda_ficheiro(lista);
    return 0;
}



Tags : , ,

0 thoughts on “parte 5 – gestão dinâmica de memória (lista ligada)”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.