CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas - 2016 Capítulo II Listas Lineares Objetivo do Lab 2 de CES-11/2016 T2: Implementar dois programas para controle de estoque de uma loja de eletrodomésticos, armazenando as informações numa lista linear 1º Programa: usando estrutura encadeada, com ponteiros para o primeiro e o último nó do encadeamento Objetivo do Lab 2 de CES-11/2016 T2: Implementar dois programas para controle de estoque de uma loja de eletrodomésticos, armazenando as informações numa lista linear 2º Programa: usando estrutura contígua Programa 2.1: Leitura, ordenação e escrita do estoque inicial O objetivo deste programa é servir como base de testes para algumas funções a serem programadas Ele conta com funções de leitura, ordenação e escrita do estoque inicial, apropriadas somente para lista encadeada Nas versões finais dos programas do Lab 2, as duas primeiras dessas funções deverão ser dispensadas e a função de escrita deverá ser tornada independente da estrutura escolhida A variável Estoque (de tipo lista) é global e não deverá ser passada como argumento para nenhuma função /* Declarações globais #include #include #include #include */ <stdio.h> <stdlib.h> <conio.h> <string.h> typedef char logic; const logic TRUE = 1, FALSE = 0; typedef char string[20]; typedef struct eletrodomestico eletrodomestico; struct eletrodomestico { Cada eletrodoméstico do string nome; estoque terá duas informações: int unids; nome e número de unidades }; estocadas typedef struct noh noh; struct noh { eletrodomestico eletro; noh *prox; }; o tipo noh nome typedef struct lista lista; struct lista { noh *inic, *fim; }; eletro unids prox typedef noh *posicao; lista Estoque; Estoque eletro eletro eletro /* Prototipos das funcoes auxiliares As funções auxiliares atuam sobre a variável global Estoque e não têm parâmetros void NovoEstoque (void); void OrdenarEstoque (void); void ListarEstoque (void); /* Funcao principal */ */ int main () { printf ("Controle do Estoque de Eletrodomesticos\n\n"); NovoEstoque (); OrdenarEstoque (); ListarEstoque (); printf ("\n\n"); system ("pause"); return 0; } void NovoEstoque () { Muito próxima da função NovaLista, posicao p; mas não retorna a lista formada int i, n; p = Estoque.inic = (noh *) malloc (sizeof (noh)); printf ("Numero de aparelhos: "); scanf ("%d", &n); Encadeia os nós a partir do campo inic da variável global Estoque if (n > 0) for (i = 1; i <= n; i++) { p->prox = (noh *) malloc (sizeof (noh)); p = p->prox; printf ("\nNome e a quantidade do %d aparelho: ", i); setbuf (stdin, NULL); scanf ("%s%d", p->eletro.nome, &p->eletro.unids); } p->prox = NULL; Dois valores lidos para cada nó: Deve-se acertar o ponteiro fim da o nome e as unidades de um Estoque.fim = p; variável Estoque eletrodoméstico } void OrdenarEstoque () { posicao p, q, min; eletrodomestico menor; for (p = Estoque.inic->prox; p != NULL && p->prox != NULL; p = p->prox) { for (menor = p->eletro, min = p, q = p->prox; q != NULL; q = q->prox) { if (strcmp (q->eletro.nome, menor.nome) < 0) { menor = q->eletro; min = q; } É o método Selection-Sort para encadeamentos, visto em CES-10 e } adaptado para a variável global Estoque if (min != p) { min->eletro = p->eletro; p->eletro = menor; } Comentários sobre esta função não serão feitos, pois } ela é usada apenas como apoio à programação de } diversas funções e será dispensada no final void ListarEstoque () { Copiar e posicao p; executar este if (Estoque.inic->prox == NULL) programa printf ("\nEstoque vazio\n"); else { printf ("\n%22s|%10s\n", "Nome ", "Unidades"); printf ("-----------------------------------\n"); for (p = Estoque.inic->prox; p != NULL; p = p->prox) printf ("%22s|%10d\n", p->eletro.nome, p->eletro.unids); } Muito próxima da função EscreverLista, printf ("\n"); mas não tem parâmetro; trabalha com a } variável global Estoque No final da programação, ela deverá ser tornada independente de estrutura de dados Lista dos operadores permitidos para a variável Estoque: 1) void InicializarEstoque (); 2) void Inserir (eletrodomestico eletro, posicao p); 3) void Deletar (posicao p); 4) void MaisUnidades (int n, posicao p); 5) void MenosUnidades (int n, posicao p); 6) infolocal Local (string nome); 7) posicao Primeira (); 8) eletrodomestico Elemento (posicao p); 9) posicao Proxima (posicao p); 10) posicao Fim (); 11) logic EstoqueVazio (); 1) void InicializarEstoque (); Alocar a variável Estoque, se for o caso, deixando-a em condições de ser usada para inserções, deleções e outros operadores Deixar essa variável vazia Na estrutura encadeada, o nó-líder deve ser alocado e os ponteiros inic e fim da variável devem apontar para ele O ponteiro do nó-líder deve ser anulado Na estrutura contígua, o campo Ultimo deve ser zerado 2) void Inserir (eletrodomestico eletro, posicao p); Foi vista nas aulas teóricas, para a estrutura sem o ponteiro para o último nó Na estrutura com esse ponteiro, cuidado ao inserir na posição de fim de lista Um novo nó passará a ser o último da lista, logo o ponteiro fim da variável Estoque deve ser alterado Essa função só será chamada quando garantidamente a variável p for uma posição em Estoque 3) void Deletar (posicao p); Foi vista nas aulas teóricas, para a estrutura sem o ponteiro para o último nó, a função Deletando, que retornava o elemento deletado Neste lab, o elemento deletado não deverá ser retornado Na estrutura com ponteiro para o último nó, cuidado quando a posição de deleção for a do último elemento Um novo nó passará a ser o último da lista, logo o ponteiro fim da variável Estoque deve ser alterado Essa função só será chamada quando garantidamente a variável p for uma posição em Estoque 4) void MaisUnidades (int n, posicao p); Adicionar mais n unidades ao eletrodoméstico da posição p Essa função só será chamada quando garantidamente a variável p for uma posição em Estoque 5) void MenosUnidades (int n, posicao p); Retirar n unidades do eletrodoméstico da posição p Essa função só será chamada quando garantidamente a variável p for uma posição em Estoque 6) infolocal Local (string nome); Retorna duas informações sobre a variável-parâmetro nome, pressupondo que os eletrodomésticos estejam ordenados alfabeticamente nos nós de Estoque: O conteúdo de nome é ou não um eletrodoméstico de Estoque Qual a posição que nome ocupa ou deveria ocupar em Estoque Essas informações devem ficar guardadas numa estrutura do tipo infolocal, conforme a seguinte declaração: typedef struct infolocal infolocal; struct infolocal {posicao posic; logic estah;}; 7) posicao Primeira (); - Posição do primeiro eletrodoméstico de Estoque 8) eletrodomestico Elemento (posicao p); - Eletrodoméstico da posição p em Estoque 9) posicao Proxima (posicao p); - Posição seguinte à p no Estoque 10) posicao Fim (); - Posição após à do último eletrodoméstico de Estoque 11) logic EstoqueVazio (); - Retorna TRUE, se Estoque estiver vazio, e FALSE, em caso contrário Exercício 2.1: Adicionar unidades a um eletrodoméstico do estoque Solicitar do operador a digitação do nome e do número de unidades a serem adicionadas O nome deve ser procurado em Estoque (a função Local responde se está e onde está ou deveria estar) Se o eletrodoméstico não estiver no estoque, deve ser inserido um nó para ele com as informações digitadas (função Inserir); a ordem alfabética não pode ser quebrada Se estiver, apenas adicionar o número de unidades digitadas àquelas já em estoque (função MaisUnidades) Acrescentar a seguinte declaração global: typedef struct infolocal infolocal; struct infolocal { posicao posic; logic estah; }; Acrescentar os seguintes protótipos de funções: void AdicionarUnidades (void); void Inserir (eletrodomestico, posicao); void MaisUnidades (int, posicao); infolocal Local (string); Trocar a função main por aquela do slide a seguir void main () { char c; printf ("Controle do Estoque de Eletrodomesticos\n\n"); NovoEstoque (); OrdenarEstoque (); ListarEstoque (); printf ("Adicionar unidades a algum eletrodomestico? (s/n): "); do c = getche (); while (c != 's' && c != 'S' && c != 'n' && c != 'N'); while (c == 's' || c == 'S') { printf ("\n\n"); AdicionarUnidades (); printf ("\n\nAdicionar unidades a algum eletrodomestico? (s/n): "); do c = getche (); while (c != 's' && c != 'S' && c != 'n' && c != 'N'); } ListarEstoque (); printf ("\n\n"); system ("pause"); return 0; } Acrescentar a seguinte função: void AdicionarUnidades () { eletrodomestico eletro; infolocal loc; string nome; int unids; printf ("Adicao de unidades a um eletrodomestico\n\n"); printf ("Nome: "); setbuf (stdin, NULL); gets (nome); Observa-se que esta printf ("Unidades adicionadas: "); função: scanf ("%d", &unids); Independe da loc = Local (nome); estrutura de dados if (loc.estah == TRUE) escolhida MaisUnidades (unids, loc.posic); else { Garante que a ordem strcpy (eletro.nome, nome); alfabética seja mantida eletro.unids = unids; Inserir (eletro, loc.posic); Pode dispensar as } funções NovoEstoque } e OrdenarEstoque Programar as seguintes funções-operadoras para Estoque: void Inserir (eletrodomestico eletro, posicao p) {- - - - -} void MaisUnidades (int unids, posicao p) {- - - - -} infolocal Local (string nome) {- - - - -} Exercício 2.2: Dar ao operador a opção de realizar as seguintes operações: Adicionar unidades de um eletrodoméstico Retirar unidades de um eletrodoméstico Pedir informações sobre o numero de unidades de um eletrodoméstico Listar todo o estoque Encerrar as operações InicializarEstoque (); ExibirMenu (); c = getche (); printf ("\n\n"); printf ("Digitado: %c\n\n", c); Mudar o miolo da while (c != 'F' && c != 'f') { função main para: switch (c) { case 'A': case 'a': AdicionarUnidades (); break; case 'R': case 'r': RetirarUnidades (); break; case 'N': case 'n': NumeroUnidsEletro (); break; case 'L': case 'l': ListarEstoque (); break; } ExibirMenu (); Observa-se que as c = getche (); printf ("\n\n"); funções NovoEstoque e printf ("Digitado: %c\n\n", c); OrdenarEstoque não estão sendo invocadas } Função ExibirMenu: Escrever na tela algo equivalente a: Digite A - para adicionar unidades a um eletrodomestico R - para retirar unidades de um eletrodomestico N - para informar o numero de unidades de um eletrodomestico L - para listar todo o estoque F - para encerrar as operacoes: Sua opcao: Função RetirarUnidades: Deve ser programada em moldes semelhantes à da função AdicionarUnidades Deve ser independente da estrutura de dados Deve solicitar do operador a digitação do nome e do número de unidades a serem retiradas O nome deve ser procurado em Estoque (a função Local responde se está e onde está ou deveria estar) Se o eletrodoméstico não estiver no estoque, deve ser emitida uma mensagem de erro Função RetirarUnidades: Se o numero de unidades a serem retiradas for menor que o numero de unidades no estoque, subtrair o número de unidades digitadas daquelas já em estoque (função MenosUnidades) Se for maior ou igual, deletar do estoque o nó do eletrodoméstico (função Deletar) Alem disso, se maior, avisar que o numero de unidades retiradas será apenas aquele em estoque Função NumeroUnidsEletro: Deve ser programada em moldes semelhantes à da função AdicionarUnidades Deve ser independente da estrutura de dados Deve solicitar do operador a digitação do nome do eletrodoméstico cujo número de unidades deseja-se conhecer O nome deve ser procurado em Estoque (a função Local responde se está e onde está ou deveria estar) Se o eletrodoméstico não estiver no estoque, deve ser emitida uma mensagem de erro Função NumeroUnidsEletro: Se estiver, colher a informação do estoque (função Elemento) Em seguida, escrever na tela o nome e o número de unidades do eletrodoméstico colhido Função ListarEstoque: Deve ser alterada para se tornar independente da estrutura de dados Poderá usar devidamente as funções-operadoras de listas EstoqueVazio, Primeira, Fim, Proxima e Elemento Funções-operadoras da lista Estoque: Devem ser programadas todas aquelas que assim ainda não foram A estrutura de dados é a encadeada apresentada no início deste documento Exercício 2.3: Trocar a estrutura de dados do programa do exercício anterior pela estrutura contígua para listas lineares Alterar no programa anterior Declarações: apenas a estrutura de dados para listas e para posição e as funções const int MAXELETROS = 100; operadoras da lista Estoque typedef struct lista lista; struct lista { eletrodomestico Eletros [MAXELETROS]; int Ultimo Ficam proibidas quaisquer alterações: }; Nas structs eletrodomestico e infolocal typedef int posicao; lista Estoque; Nas funções main, ExibirMenu, AdicionarUnidades, RetirarUnidades, NumeroUnidsEletro e ListarEstoque