Linha | Codigo |
001 | // Prof. Leo^nidas - http://www.matematica.br http://line.ime.usp.br |
002 | // MAC0122 - 2017/10/02 |
003 | |
004 | // Introducao ao conceito de PILHA (primeiro a entrar, primeiro a sair) ou "stack" (LIFO - "last in, first out") |
005 | // Usa conceito de apontador para apontador ("**apont") |
006 | // Exemplo usando lista ligada (com 'typedef' e 'struct'), inserir e remover da pilha |
007 | |
008 | // Exercicio: Fazer uma implementacao equivalente utilizando vetor no lugar de lista ligada. |
009 | |
010 | // gcc -fsanitize=address -g -o introducao_pilha_lista_ligada_struct introducao_pilha_lista_ligada_struct.c |
011 | |
012 | #include <stdio.h> |
013 | #include <string.h> // para 'strcpy(...)' |
014 | #include <stdlib.h> // para 'malloc(...)' |
015 | |
016 | #define TAM 10 // limite para numero de caracteres em campo do registro |
017 | #define M 5 // limite para vetor de registros |
018 | |
019 | typedef struct reg { // define estrutura 'dado' |
020 | int id; |
021 | char nome[TAM]; |
022 | struct reg *prox; // aponta para uma estrutura 'dado' |
023 | } tipoRegistro; |
024 | |
025 | // Para depuracao: imprimir registro |
026 | void imprimir (tipoRegistro *item) { |
027 | if (item == NULL) { // pilha vazia |
028 | printf("<vazio>"); |
029 | return; |
030 | } |
031 | printf("(%d, %s)", item->id, item->nome); |
032 | } |
033 | |
034 | // Testar: imprimir pilha toda |
035 | void imprimirPilhaToda (tipoRegistro *topo) { |
036 | tipoRegistro *item = topo; |
037 | int i; |
038 | printf("Situacao da pilha: "); |
039 | while (item!=NULL) { |
040 | imprimir(item); |
041 | printf(" "); |
042 | item = item->prox; //printf(" - %s\n", nomes[i]); |
043 | } |
044 | printf("\n"); |
045 | } |
046 | |
047 | // Criar item de registro |
048 | tipoRegistro *criar (int id, char *nome) { |
049 | tipoRegistro *item = malloc(sizeof(tipoRegistro)); |
050 | // Nao basta apontar para "string" apontada por "nome", precisa copiar todos seus caracteres na posicao nova apontada por "item" |
051 | strcpy(item->nome, nome); |
052 | item->id = id; |
053 | item->prox = NULL; // importante! |
054 | return item; |
055 | } |
056 | |
057 | // Inserir no topo da pilha: versao 1 devolvendo o topo |
058 | tipoRegistro *inserir (tipoRegistro *item, tipoRegistro *topo) { |
059 | if (topo != NULL) { // pilha vazia |
060 | item->prox = topo; |
061 | return item; |
062 | } |
063 | return item; |
064 | } |
065 | |
066 | // Inserir no topo da pilha: versao 2 atualizando o topo |
067 | void inserirV2 (tipoRegistro *item, tipoRegistro **topo) { |
068 | if (*topo != NULL) { // pilha vazia (apontado eh vazio) |
069 | item->prox = *topo; |
070 | } |
071 | *topo = item; // para alterar quem chama |
072 | } |
073 | |
074 | // Remover do topo da pilha (apos usar o dado poderia-se devolve-lo `a pilha de memoria com "free(item);") |
075 | // Tem que passar endereco do apontador para apontador de registros para poder altera-lo |
076 | tipoRegistro *remover (tipoRegistro **topo) { |
077 | tipoRegistro *item; |
078 | if (*topo == NULL) { // pilha vazia |
079 | return NULL; |
080 | } |
081 | item = *topo; |
082 | *topo = (*topo)->prox; |
083 | return item; |
084 | } |
085 | |
086 | int main (void) { |
087 | int i; |
088 | char nomes[][TAM] = { "aluno 1", "aluno 2", "aluno 3", "aluno 4", "aluno 5" }; |
089 | tipoRegistro *item0, *item, *topo = NULL; |
090 | |
091 | printf("Simulando operacoes:\n"); |
092 | for (i=0; i<5; i++) { // inserir os 5 item |
093 | item = criar(i, nomes[i]); // imprimirPilhaToda(item); |
094 | if (i%2 == 0) // usar versao 1 |
095 | topo = inserir(item, topo); |
096 | else // usar versao 2 |
097 | inserirV2(item, &topo); // tem que passar o local em que o apontador para topo esta (para altera-lo) |
098 | imprimirPilhaToda(topo); |
099 | } |
100 | |
101 | item0 = remover(&topo); // remover item "(4, aluno 5)" |
102 | printf("Removido item: "); imprimir(item0); printf("\n"); |
103 | |
104 | item = remover(&topo); // remover item "(3, aluno 4)" |
105 | printf("Removido item: "); imprimir(item); printf("\n"); |
106 | |
107 | inserirV2(item0, &topo); // inserir item "(4, aluno 5)" |
108 | printf("Inserido item: "); imprimir(item0); printf("\n"); |
109 | |
110 | printf("Situacao final da pilha: "); |
111 | imprimirPilhaToda(topo); |
112 | return 0; |
113 | } |