Ir ao conteúdo
  • Cadastre-se

C Transformar essa lista simplesmente encadeada em uma simplesmente circular


Guic
Ir à solução Resolvido por arfneto,

Posts recomendados

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

// definição de uma lista simples

typedef struct{
	struct Musica *primeiro;
	char nome[30];
	struct Musica *proxima; 
}Musica;

void inicializarMusica(Musica **musica);
void inserirMusica(Musica **musica,char auxMusica[30]);
void exibirMusicas(Musica **musica);
void removerMusicaDaLista(Musica **musica,char auxMusica[30]);

void main (void){
	setlocale(LC_ALL, "Portuguese");
	Musica *m;
	inicializarMusica(&m);
	printf("\n\n");
	inserirMusica(&m,"Girls Like You");
	inserirMusica(&m,"Thunder");
	inserirMusica(&m,"Monster");
	printf("Musicas na lista:\n");
	exibirMusicas(&m);
	printf("Fim da lista\n\n");
	printf("Tem %d musicas na lista!\n\n",qtdElementos(&m));
	removerMusicaDaLista(&m,"Thunder");
	printf("Musicas na lista:\n");
	exibirMusicas(&m);
	printf("Fim da lista\n\n");
	printf("Tem %d musicas na lista!\n\n",qtdElementos(&m));
	buscarMusica(&m, "Thunder",0);
	apagarListaMusica(&m);
	exibirMusicas(&m);
}

void inicializarMusica(Musica **musica){
	*musica = NULL;
	printf("Pessoa Inicializada");	
}

void inserirMusica(Musica **musica,char auxMusica[30]){
	
	if(*musica == NULL){
		*musica = (Musica *) malloc(sizeof(Musica));
		strcpy((*musica)->nome,auxMusica);
		(*musica)->proxima = NULL;
	}else{
		inserirMusica(&((*musica)->proxima),auxMusica);
	}
}

void exibirMusicas(Musica **musica){
	if(*musica != NULL){
		printf("%s\n",(*musica)->nome);
		if((*musica)->proxima != NULL){
			exibirMusicas(&((*musica)->proxima));
		}
	}else{
		printf("\nNão exite uma lista!\n");
	}
}

void buscarMusica(Musica **musica, char auxMusica[30],int indice){
	Musica *auxLista;
	if((*musica) != NULL){
		if(strcmp((*musica)->nome,auxMusica) == 0){
			printf("A musica %s foi encontrado na posição %d\n",auxMusica,indice);	
		}else{
			buscarMusica(&((*musica)->proxima),auxMusica,++indice);
		}		
	}else{
		printf("A musica  %s não foi encontrada!\n",auxMusica);
	}
}

void removerMusicaDaLista(Musica **musica,char auxMusica[30]){
	Musica *auxLista;
	if((*musica) != NULL){
		if(strcmp((*musica)->nome,auxMusica) == 0){
			if((*musica)->proxima == NULL){
				(*musica) = NULL;
				free (* musica);
	            printf("A musica %s foi excluida com sucesso\n\n", auxMusica);
			}else{
				auxLista = *musica;
				*musica = (*musica)->proxima;
				auxLista->proxima = NULL;
				free (auxLista->proxima);				
			}			
		}else{
			removerMusicaDaLista(&((*musica)->proxima),auxMusica);
		}
	}else{
		printf("A musica  %s não foi encontrada!\n",auxMusica);
	}
}

void apagarListaMusica(Musica **musica){
	if(*musica != NULL){
		apagarListaMusica(&((*musica)->proxima));
		(*musica) = NULL;
		free (*musica);
	}
}

int qtdElementos(Musica **musica){         	// recursividade indireta
	int contador = 0;
	return contar(musica, contador);	
}

int contar(Musica **musica, int contador){  	// recursividade direta
	if(*musica != NULL){
	
		contar(&((*musica)->proxima), ++contador);
			
	}else return contador;	 
}

Preciso transformar essa lista em circular encadeada 
Poderiam me ajudar por favor

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Eu não entendi muito bem, aparentemente, a lista deveria começar simplesmente encadeada e depois virar circular, eu iniciei a sua ideia.

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

typedef struct NO {
    NO * next;
    int data;
} NO;

typedef struct L {
    NO * node;
    NO * last;
    int idx;
    int limit;
} L;

void add(L * list, int data) {
    if (list->idx == list->limit) {
        list->last->next = list->node; // aponta o final para o inicio, criando um loop de referencias
    }

    if (list->node == NULL) {
        list->node = (NO * ) malloc(sizeof(NO));
        list->node->data = data;
        list->node->next = NULL;
        list->last = list->node;
    } else if (list->idx < list->limit) {
        NO * aux;
        NO * l = list->node;

        while (l != NULL) {
            aux = l;
            l = l->next;
        }
        aux->next = (NO * ) malloc(sizeof(NO));
        aux->next->data = data;

        list->last = aux->next; // manter atualizada a referencia pro ultimo elemento
    } else {
        NO * l = list->node;
        int offset = 0;

        while (offset < list->idx) {
            l = l->next;
            offset++;
        }
        l->data = data;
    }
    list->idx++;
}

// caso queira testar se existe de fato um looping infinito
void show(L * list) {
    NO * aux;
    aux = list->node;

    int max = 20;
    int i = 0;
    int j = 1;

    while (aux != NULL && max > i) {
        printf("%d\n", aux->data);
        aux = aux->next;
        if (list->limit == j) {
            printf("volta pro inicio---\n\n");
            j = 0;
        }
        i++;
        j++;
    }
}

int main() {
    // criar a lista
    L * list = (L * ) malloc(sizeof(L));
    list->limit = 5;
    list->idx = 0;

    add(list, 1);
    add(list, 2);
    add(list, 3);
    add(list, 4);
    add(list, 5);

    // caso especial->quando a lista chega no limite e cria um loop
    add(list, -1);
    add(list, -2);

    show(list);
}

image.thumb.png.3b2ead9ac25d37f5a62d5266d1327794.png 

 

Se você estava travado em "transformar a encadeada em circular" essa seria uma ideia

Link para o comentário
Compartilhar em outros sites

  • Solução
// definição de uma lista simples

typedef struct{
	struct Musica *primeiro;
	char nome[30];
	struct Musica *proxima; 
}Musica;

 

Sugiro que evite esse tipo de comentário. Comente o que está fazendo e porque está fazendo, como um recado para você mesmo daqui um tempo, ou para quem esteja lendo seu programa. E evite esses comentários meio que óbvios.

 

Sobre a estrutura

 

Evite ao máximo escrever assim.

 

Uma lista é um container. Pode ter qualquer coisa dentro. Mas a lista é feita de nós, os tais links, um que aponta para o outro. DENTRO desses links é que estão os dados. As músicas. Só que no próximo programa serão livros, carros, int, char.

 

Não misture as coisas. Só vai dificultar sua vida. A lista é genérica. Pode ser de qualquer coisa. 

 

Veja esse exemplo:

 

typedef struct st_no
{
    char nome[30];

}   Musica;

 

Esse é o dado.

 

A lista é de nós:
 

typedef struct st_node
{

    Info*           info;
    struct st_node* ini;
    struct st_node* fim;

} Node;

 

E a lista o que é?
 

Uma série de links. Seu modelo deve representar isso.

 

typedef struct
{
    Node*    ini;
    Node*    fim;
    unsigned size;  // tamanho

} Lista;

 

O que falta?

 

typedef Musica Info;

 

Pronto: nesse programa a lista é de Musica.

 

No geral se usa void* como o tipo da lista, para ficar genérico. Pense nisso.

 

Em resumo, juntando tudo:

 

typedef struct 
{
    char nome[30];

} Musica;

typedef Musica Info;

typedef struct st_node
{
    Info*           info;
    struct st_node* ini;
    struct st_node* fim;

} Node;

typedef struct
{
    Node*    ini;
    Node*    fim;
    unsigned size;  // tamanho

} Lista;

 

É muito mais simples programar assim. E seu próximo programa de listas pode ser o mesmo: a lista é uma lista, uma série de links de um Node para outro.

 

Sobre as funções

 


void inicializarMusica(Musica **musica);
void inserirMusica(Musica **musica,char auxMusica[30]);
void exibirMusicas(Musica **musica);
void removerMusicaDaLista(Musica **musica,char auxMusica[30]);

 

Aqui você tem o reflexo do problema de que falei acima. Não retorne void. Não misture lista com musicas. Não tem sentido inicializarMusica por exemplo. 

 

Se Musica é um dado que vai estar numa lista não deveria ter referência a Musica**. Pense nisso.

 

O normal:

 

Lista*  inicializarLista();
int     inserir_na_lista(Info* info, Lista* l);
int     exibir_musicas(Lista* lista);
int     remover_da_lista(Info* info, Lista* l);

 

Compare: Não tem referência a Musica na Lista. Apenas em exibir_musicas aparece a Lista porque afinal é onde estão as músicas.

 

E a lista circular?

 

Lista circular não existe. Trata-se apenas de uma disciplina de inserção. Você coloca um limite na lista e ao chegar a esse limite não cria mais nós: apenas passa a escrever o novo em cima do mais antigo. Só isso.

Algo assim:

 

typedef struct
{
    Node*    ini;
    Node*    fim;
    unsigned size;  // tamanho
    unsigned limite;  // tamanho

} Lista;

 

E aí dependendo do modelo você implementa a inserção de acordo. É só isso: um critério. O que fazer ao atingir o limite. Em relação a isso uma maneira comum de implementar a lista é ter um registro fixo, que é chamado de sentinela na literatura --- sentinel record --- para facilitar a programação: a lista vazia só tem o sentinela. E assim evita que o programa se perca no tal círculo de nós.

 

 

 

 

 

 

 

 

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

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!