Ir ao conteúdo
  • Cadastre-se

C Inserir ordenadamente na lista circular


Posts recomendados

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!

Link para o comentário
Compartilhar em outros sites

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.

Link para o comentário
Compartilhar em outros sites

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