Ir ao conteúdo

Posts recomendados

Postado

Eu preciso de ajuda para inserir e imprimir ordenadamente uma lista circular duplamente encadeada em c, mas não estou conseguindo. O meu código está inserindo e imprimindo a lista de maneira desordenada. Alguém pode me ajudar? Vou deixar abaixo o código:

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

typedef struct mercadoria {
    char nome[20];
    float preco;
} Mercadoria;

typedef Mercadoria Tipo;

#define TRUE 1
#define FALSE 0

typedef struct node {
    Tipo c;
    struct node *prev;
    struct node *next;
} Node;

Node *corrente;

int lcdeCreate() {
	corrente = NULL;
    return TRUE;
}

int lcdeDestroy() {
	while (corrente != NULL) {
	    Tipo aux;
	    lcdeRemove(&aux);
	    printf("\n%s removido.\n", aux.nome);
    }
	return TRUE;
}

Node *encadeiaNovoElemento(Tipo c, Node *p1, Node *p2) {
	Node *aux;
	aux = (Node *) malloc (sizeof(Node));
	aux->c = c;
	aux->next = aux->prev = NULL;
	if (p1 == NULL) {
	    aux->next = aux;
        aux->prev = aux;
        return aux;
    }
    aux->prev = p1;
	aux->next = p2;
	p1->next = aux;
	p2->prev = aux;
	return aux;
}

int lcdeIn(Tipo c) {
	printf("\n[%s %f]\n", c.nome, c.preco);
	system("PAUSE");
	Node *p1, *p2;
    //A inserção vai ocorrer entre p1 e p2 ou após o corrente - AQUI ESTÁ O ERRO!!! Preciso que a inserção seja ordenada!
    p1 = corrente;
    if (corrente != NULL)
        p2 = corrente->next;
    corrente = encadeiaNovoElemento(c, p1, p2);
    return TRUE;
}

int lcdeOut(Tipo *c) {
	if (corrente == NULL) {
        return FALSE;
    }
	*c = corrente->c;
	return TRUE;
}

int lcdeRemove(Tipo *c) {
	if (corrente == NULL) {
        return FALSE;
    }
    Node *aux = corrente;
    *c = aux->c;
    Node *p1 = aux->prev;
	Node *p2 = aux->next;
	if(aux == p2) {
	    corrente = NULL;
	} else {
		p1->next = p2;
	    p2->prev = p1;
	    corrente = p2;
	}
	free(aux);
	return TRUE;
}

int lcdeNext() {
	return TRUE;
}

int lcdePrevious() {
	if (corrente == NULL) {
	    return FALSE;
    }
    corrente = corrente->prev;
	return TRUE;
}

int lcdePrint() {
	if (corrente == NULL) {
        printf("\nLista vazia.\n");
        return TRUE;
    }
    printf("->");
	Node *aux = corrente;
	printf("[%s]->", corrente->c.nome);
    aux = corrente->next;
    while(aux != corrente) {
        printf("%s->", aux->c.nome);
        aux = aux->next;
    }
    return TRUE;
}

void menu() {
    system("cls");
    printf("Lista Circular Mercadorias\n");
    printf("i - insere mercadoria\n");
    printf("d - delete corrente\n");
    printf("p - próxima\n");
    printf("a - anterior\n");
    printf("s - sair\n");
    lcdePrint();
}

void leMercadoria() {
    Mercadoria m;
    printf("\nDigite o nome da mercadoria: ");
    scanf("%s", m.nome);
	printf("\nDigite o preço: ");
	scanf("%f", &m.preco);
    lcdeIn(m);
}

int main() {
	setlocale(LC_ALL,"portuguese");
	lcdeCreate();
	while (TRUE) {
        menu();
        char letra = getch();
        if (letra == 's')
            //exit(1);
            break;
        else if (letra == 'i') {
            leMercadoria();
        } else if (letra == 'p') {
            lcdeNext();
        } else if (letra == 'a') {
            lcdePrevious();
        } else if (letra == 'd') {
        	Tipo c;
            if (lcdeRemove(&c) == TRUE)
            printf("\nRemovido %s.\n", c.nome);
            else
            printf("\nNada a fazer.\n");
            system("PAUSE");
        }
    }
    lcdeDestroy();
	return 0;
}

A propósito, também preciso fazer uma função de busca. Essa função recebe um valor e tem que buscar se esse valor é correspondente ao valor de alguma chave da lista circular e então exibir o nome dessa chave. Mas não sei fazer isso. Podem me ajudar, por favor? Desde já, obrigado!

Postado

Uma lista é um container: ela tem nós dentro e dentro dos nós tem dados. Em geral um ponteiro para um dado dentro de cada nó. 

 

E a lista não trata os dados diretamente.

 

Não use variáveis globais.
 

Declare a sua lista como tal e não como um nó. E inclua dentro dela a capacidade e o total atual de nós. Em geral numa lista circular vai achar mais fácil usar o que se chama de registro SENTINELA --- sentinel record --- que é um nó especial que marca o início e o fim da lista. Simplifica muito a programação. E na prática só não se usa um sentinela quando se tem uma quantia mínima de memória e o nó é muito grande. Difícil de acontecer hoje em dia...

É uma coisa ingênua até: ao criar a lista ela tem só o sentinela. Então começa e termina no mesmo lugar.

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...