1
- Estruturas e aplicações
MCTA028 – Programação Estruturada
Luiz Rozante 3Q-2018
Material preparado a partir de slides dos profs. Jesús Mena-Chalco e Fabrício Olivetti
Estruturas (=registros)
3
Linguagem C: Tipos de dados
Tipos de dados primários.
Tipos de dados derivados.
Tipos definidos pelo usuário.
(*) Fonte: http://www.studytonight.com/c/datatype-in-c.php
Para definir e usar um tipo de usuário
Definição Declaração Acesso
Em C, structs permitem definir tipos de dados como uma composição de tipos já existentes.
O uso de tipos de usuário exige três “passos”:
Definição de tipo de usuário
Podemos definir (“dizer como é”) um tipo novo usando tipos já existentes (definidos ou pré-definidos).
Forma geral:
struct nome_tipo {
nome_tipo_1 nome_membro_1;
nome_tipo_2 nome_membro_2;
...
nome_tipo_k nome_membro_k;
};
Declaração de variáveis de tipo de usuário
Declaramos uma variável de tipo definido (de
usuário) da mesma forma que declaramos uma de tipo pré-definido.
struct nome_tipo nome_var;
Definição e declaração de tipos de usuário com a cláusula typedef (redefinidor de nomes de tipo).
Forma geral:
typedef struct {
nome_tipo_1 nome_membro_1;
nome_tipo_2 nome_membro_2;
...
nome_tipo_k nome_membro_k;
}nome_tipo_novo;
nome_tipo_novo nome_var;
definição
declaração
Acesso a variáveis de tipo de usuário
O acesso aos membros (campos) de variáveis declaradas a partir de tipo de usuário (definido) é feito através do operador de acesso:
– ponto (´ . ´),
– seta (' -> '), se ponteiro para estrutura (registro).
9
Estruturas
1. #include <stdio.h>
2.
3. struct ALUNO { //Definição da estrutura
4. float nota;
5. int cod;
6. char conceito;
7. };
1. void main() {
2. int i;
3. struct ALUNO jose, ana; // Declara variáveis
4. struct ALUNO turma[7]; // do tipo ALUNO
5. jose.nota = 7.0; // Acessa membros da
6. jose.cod = 1212; // variável jose
7. if (jose.nota < 7.0) {
8. jose.conceito = ‘R’;
9. }
10. else {
11. jose.conceito = ‘A’;
12. }
13.
14. for (i=0 ; i<=6 ; i++) {
15. turma[i].cod = 100 + i;
• turma[i].nota = 0.0;
1. }
2. }
1. #include <stdio.h>
2. struct FICHA { //Definição da estrutura FICHA
3. char nome[40];
4. int cod;
5. float salario;
6. };
1. void le_cadastro();
1. /* declara um vetor tipo FICHA */
2. struct FICHA cadastro[100];
1. void main() { le_cadastro(); }
1. void le_cadastro() {
2. int i;
3. for (i=0 ; i<=99 ; i++) { 4. printf(“Nome = “);
5. gets(cadastro[i].nome);
6. printf(“\n “);
7. printf(“Código = “);
8. scanf(“%d\n”, &cadastro[i].cod);
• printf(“\n “);
1. printf(“Salário = “);
• scanf(“%f\n”, &cadastro[i].salario);
1. } 2. }
1)
1. #include <stdio.h>
2. #include <conio.h>
3. struct DATA { //Definição da estrutura DATA 4. int dia;
5. char mes[10];
6. int ano;
7. };
1. struct VENDA { //Definição da estrutura VENDA 2. int cod;
3. int qtde;
4. float preco;
5. struct DATA dt_venda;
6. };
1. void impr_venda();
2. void impr_vendaS();
1. /* inicialização da variável x tipo VENDA */
2. struct VENDA x={12,10,23.4,{5,”Mar”,2002}};
1. /* declaração de uma matriz tipo VENDA */
2. struct VENDA reg_venda[1000];
1. void main() {
2. impr_venda();
3. impr_vendaS();
4. }
2)
24. void impr_venda() {
25. printf(“Cod= %d\n”, x.cod);
26. printf(“Qtde= %d\n”, x.qtde);
27. printf(“Preço= %f\n”, x.preco);
28. printf(“Data da venda = %d/%s/%d ”,
29. x.dt_venda.dia,
30. x.dt_venda.mes,
31. x.dt_venda.ano);
32. }
24. void impr_vendaS() {
25. int i;
26. for (i=0 ; i<=999 ; i++) {
27. printf(“Cod = %d\n”,reg_venda[i].cod);
28. printf(“Qtde= %d\n”,reg_venda[i].qtde);
29. printf(“Preço=%f\n”,reg_venda[i].preco);
30. printf(“Data da venda = %d/%s/%d ”,
31. reg_venda[i].dt_venda.dia,
32. reg_venda[i].dt_venda.mes,
33. reg_venda[i].dt_venda.ano);
34. }
35. }
2)
Estruturas
Operador de acesso indireto
Tipos abstratos de dados (TAD)
Para resolver um problema é necessário escolher uma
abstração da realidade, em geral mediante a definição de um conjunto de dados que representa a situação real
A seguir, deve ser escolhida a forma de representar esses dados
A escolha da representação dos dados é determinada, entre outras, pelas operações a serem realizadas sobre os dados
15
Exemplo de TAD: Listas Lineares
●
Sequência de zero ou mais itens x
1, x
2, ... , x
n, na qual x
ié de um determinado tipo e n representa o tamanho da lista linear
●
Sua principal propriedade estrutural envolve as posições relativas dos itens em uma dimensão
–
Assumindo n >= 1, x
1é o primeiro item da lista e x
né o último item da lista
–
x
iprecede x
i+1para i = 1, 2, . . ., n – 1
–
x
isucede x
i-1para i = 2, 3, . . ., n
–
o elemento x
ié dito estar na i-ésima posição da lista
Listas Lineares
●
Muitas aplicações
●
Principal aplicação: representação interna de conjuntos.
17
Listas Lineares: Implementações
●
Pode ser implementada de diferentes maneiras
– Estática
● todo o espaço de memória a ser utilizado (para
armazenar os itens) é reservado (alocado) no início da execução do programa ou módulo
● esse espaço de memória permanece reservado durante toda a execução do programa, independente de estar sendo efetivamente utilizado ou não
– Dinâmica
● o espaço de memória a ser utilizado (para armazenar os itens) pode ser reservado (alocado) no decorrer da execução de um programa ou módulo, quando for
efetivamente necessário
● o espaço reservado pode ser liberado durante a execução do programa, quando não for mais necessário
Listas Lineares - Estática
●
Podem dispor os seus elementos de maneira
–
Seqüencial: os itens ficam, necessariamente, em sequência (um ao lado do outro) na
memória
–
Encadeada: os itens não estão,
necessariamente, em posições de memória adjacentes (sequência lógica ou virtual)
19
Listas Lineares – Estática Seqüencial
●
Os itens da lista são armazenados em posições contíguas de memória
●
A lista pode ser percorrida em qualquer direção
●
A inserção de um novo item pode ser realizada após o último item com
custo constante
O(1)●
A inserção de um novo item no meio da lista requer um deslocamento de todos os itens localizados após o ponto de inserção O(n)
●
Retirar um item do início da lista requer um deslocamento de itens para preencher o espaço deixado vazio O(n)
Itens Índices
X1 X2
Xn
MaxTam 1
2
n
.. .
.. .
Listas Lineares – Estática Seqüencial ( TAD)
●
Para a definição de um TAD, o conjunto de operações a ser definido depende de cada aplicação
●
Exemplos:
–
1. Criar uma lista linear vazia
–
2. Inserir um novo item imediatamente após o i-ésimo item
–
3. Retirar o i-ésimo item
–
4. Localizar o i-ésimo item para examinar e/ou alterar o conteúdo de seus componentes.
–
5. Combinar duas ou mais listas lineares em uma lista única
–
6. Partir uma lista linear em duas ou mais listas
–
7. Fazer uma cópia da lista linear
–
8. Ordenar os itens da lista em ordem ascendente ou
descendente, de acordo com alguns de seus componentes
–
9. Pesquisar a ocorrência de um item com um valor particular em algum componente
21
Listas Lineares – Estática Seqüencial
Vantagens/Desvantagens
●
Vantagens
– acesso direto indexado a qualquer elemento da lista
– tempo constante para acessar o i-ésimo item - dependerá somente do índice
●
Desvantagens
– movimentação quando o item é eliminado/inserido
– tamanho máximo pré-estimado
●
Diante disso, quando usar?
– listas pequenas
– inserção/remoção no fim da lista
– tamanho máximo bem definido
MC-1424 Algoritmos e Estruturas de Dados I - 2° trimestre de 2009
Listas Lineares – Estática Seqüencial
Programa em C
#include <stdio.h>
#include <stdlib.h>
#define TAM_MAX 5
#define NULO -9999999
int insere (int lista[], int *n, int chave);
int remove_final (int lista[], int *n);
int remove_inicio (int lista[], int *n);
int imprime (int lista[], int n);
char menu(void);
main() {
int lista[TAM_MAX];
int num_atual = 0;
...
}
23
Listas Lineares – Estática Seqüencial
Função: Inserir no final
int insere (int lista[], int *n, int chave) {
if (*n == TAM_MAX) return (NULO);
lista[(*n)++] = chave;
return (0);
}
Listas Lineares – Estática Seqüencial
Função: Remover do final
int remove_final (int lista[], int *n) {
if (*n == 0) return (NULO);
return (lista[--(*n)]);
}
25
Listas Lineares – Estática Seqüencial
Função: Remover do início
int remove_inicio (int lista[], int *n) {
int i, primeiro;
if (*n == 0) return (NULO);
primeiro = lista[0];
for (i=1; i < *n; i++)
lista[i-1]= lista[i];
(*n)--;
return primeiro;
} Complexidade: (?)
Listas Lineares – Estática Seqüencial
Função: Imprimir lista
int imprime (int lista[], int n) {
int i;
if (n == 0)
printf ("Lista vazia!\n");
else {
printf ("%d elementos na lista\n", n);
for (i=0; i < n; i++)
printf ("Elemento %d = %d\n", i+1, lista[i]);
}
return (0);
}
27
Listas Lineares – Estática Seqüencial
Função: Busca lista
Exercício: Como seria a função de busca na lista ?
Listas Lineares – Estática Seqüencial
Função: Busca lista
Exercício: Como seria a função de busca na lista ?
int busca (int lista[], int n, int chave){
int i, achou = 0;
if (n == 0)
return(achou);
else {
for(i = 0;i < n; i++){
if(lista[i] == chave) achou = 1;
}
return (achou);
}
29
Algumas implementações possíveis
●
Na forma Dinâmica como ponteiros de nós, a lista pode ser implementada de várias formas, por exemplo:
–
Lista Encadeada Simples
–
Lista com Descritor
–
Lista Duplamente Encadeada
Lista Dinâmica Encadeada
● Numa lista encadeada, um espaço de memória é alocado para cada novo elemento (item) inserido na estrutura
– O espaço total de memória é proporcional ao número de elementos
– Não há garantia de que os elementos da lista ocuparão espaço de memória contíguo não há acesso direto aos elementos
● Para percorrer todos os elementos da lista é necessário guardar o seu encadeamento
– Armazena-se, junto com a informação de cada elemento, um ponteiro para o próximo elemento da lista
31
Info1 Info2 Info3
Prim
NULL
Lista Dinâmica Encadeada
●
Os itens da lista são nós com um dos componentes destinado a guardar o endereço do nó sucessor
●
Ex: L = anta, cabra, gato, pato, rato
●
●
onde cada nó é:
– Diz-se que cada nó aponta para o próximo nó
– O próximo do último nó é um apontador para NULL
– É necessário um apontador para o primeiro nó da lista
Lista Dinâmica Encadeada
Estrutura auto-referenciada
33
● Exemplo: o nó de uma lista para armazenar números inteiros pode ser representado em C
struct { int info;
struct no *proximo;
}no;
● Estrutura auto-referenciada possui um campo que é um ponteiro para uma próxima estrutura do mesmo tipo
● Essa estrutura representa um nó da lista, e a estrutura de lista encadeada é representada pelo ponteiro para o primeiro elemento
Lista Dinâmica Encadeada
TAD
● Para a definição de um TAD, o conjunto de operações a ser definido depende de cada aplicação
● Exemplos:
– 1. Criar uma lista vazia
– 2. Verificar se a lista está vazia
– 3. Inserir um novo item no início da lista
– 4. Inserir um novo item no final da lista
– 5. Retirar um item da lista no começo
– 6. Retirar um item da lista no fim
– 7. Buscar um item na lista
– 8. Imprimir os itens da lista
– 9. Determinar o comprimento da lista
– 10. Liberar a lista
– ...
Lista Dinâmica Encadeada Simples
Análise de algumas operações
●
Função de inserção no início da lista
– Para cada elemento inserido é necessário alocar dinamicamente a memória necessária
– Nota importante: o ponteiro que representa a lista deve ter seu valor atualizado
35
Info1 Info2 Info3
Prim
NULL
Novo
Lista Dinâmica Encadeada Simples
Análise de algumas operações
●
Função que retira um elemento da lista
– Duas situações tem que ser consideradas
● (a) Remoção no início da lista
● (b) Remoção no “meio“ da lista
Info1 Info2 Info3
Prim
NULL
Info1 Info2 Info3
Prim
NULL
(a)
(b)
Lista encadeada (código): tipos e ponteiros
1.
#include <stdio.h>2.
#include <stdlib.h>3.
typedef struct {4.
int valor;5.
struct nodo *prox;6.
}nodo;7.
nodo *prim;8.
nodo *p;9.
nodo *q;10.
void cria_lista_vazia();11.
void verifica_se_lista_vazia();12.
void inclui_inicio(int x);13.
void inclui_fim(int x);14.
void imprime_lista();15.
void remove_inicio();16.
void remove_fim();Código: main
1. int main(int argc, char** argv) {
2. cria_lista_vazia();
3. printf("\n");
4. verifica_se_lista_vazia();
5. inclui_inicio(10);
6. inclui_inicio(12);
7. inclui_fim(30);
8. inclui_fim(40);
9. remove_inicio();
10. remove_fim();
11. imprime_lista();
12. return (EXIT_SUCCESS);
13. }
Código: cria lista vazia
1. void cria_lista_vazia(){
2. prim = NULL;
3. printf("criei lista vazia\n");
4. }
Código: verifica se é vazia
1. void verifica_se_lista_vazia(){
2. if (prim == NULL){
3. printf("a lista está lista vazia\n");
4. printf("prim = %p \n", prim);
5. }
6. else {
7. printf("a lista NÃO está vazia");
8. printf("prim = %p \n", prim);
9. }
10. }
Código: inserir no início
1. void inclui_inicio(int x){
2. if ((p = (struct nodo*) malloc(sizeof(nodo))) == NULL) {
3. printf(" nao consegui alocar memoria para p\n");
4. exit(0);
5. }
6. p->prox = prim;
7. p->valor = x;
8. prim = p;
9. }
Código: inserir no fim
1. void inclui_fim(int x){
2. if ((p = (struct nodo*) malloc(sizeof(nodo))) == NULL) {
3. printf(" nao consegui alocar memoria para p\n");
4. exit(0);
5. }
6. q = prim;
7. while (q->prox != NULL){
8. q = q->prox;
9. }
10. p->valor = x;
11. q->prox = p;
12. p->prox = NULL;
Código: excluir no começo
1. void remove_inicio(){
2. p = prim->prox;
3. free(prim);
4. prim = p;
5. }
Código: excluir no fim
1. void remove_fim(){
2. q = prim->prox;
3. while (q->prox != NULL){
4. p = q;
5. q = q->prox;
6. }
7. free(q);
8. p->prox = NULL;
9. }
Código: imprimir
1. void imprime_lista(){
2. p = prim;
3. do {
4. printf(" %d ", p->valor);
5. p = p->prox;
6. }while (p->prox != NULL);
7. printf(" %d ", p->valor);
8. printf("\n");
9. }
Comparação entre as estratégias
Estática Seqüencial vs. Dinâmica Encadeada
● Quando é melhor utilizar uma implementação ou outra?
– Principais características que devem ser consideradas
● A implementação estática (array) requer a
especificação do tamanho máximo da lista em tempo de compilação. Se não for possível especificar o tamanho máximo que a lista pode atingir, seria mais adequado escolher a implementação dinâmica
● A implementação estática pode desperdiçar espaço. A implementação dinâmica requer espaço para os
ponteiros em cada célula. Em diferentes circunstâncias um método pode acabar utilizando mais espaço do que o outro
Comparação entre as estratégias
Estática Seqüencial vs. Dinâmica Encadeada
47
●
Quando é melhor utilizar uma implementação ou outra?
– Principais características que devem ser consideradas
● Algumas operações são mais custosas em uma implementação e não na outra
– Inserção e deleção no início tempo constante na implementação dinâmica encadeada, mas tempo proporcional ao número de elementos na
implementação estática
– No final tempo constante na implementação estática, mas tempo proporcional ao número de
elementos na implementação dinâmica encadeada
Lista Dinâmica Encadeada
Alguns Problemas
●
Caracteriza-se por formar um encadeamento simples entre os elementos
– Cada elemento armazena um ponteiro para o próximo elemento da lista
●
Problemas dessa estratégia
– Não temos como percorrer a lista em ordem inversa de maneira eficiente
– Dificulta a retirada de um elemento da lista. Mesmo se tivermos o ponteiro para o elemento que se deseja retirar, temos que
percorrer a lista para encontrar o elemento anterior
●
Solução
– Lista com descritor?
– Lista Dinâmica Duplamente Encadeada
Outro exemplo de TAD: Pilhas
49
Pilhas
É a estrutura de dados mais utilizada em programação, sendo inclusive implementada diretamente pelo hardware da maioria das máquinas modernas
A idéia fundamental da pilha é que todo o acesso a seus elementos é feito por meio do seu topo
É um conceito semelhante a qualquer tipo de pilha: pratos,
livros, CDs, etc
Pilhas (Stacks)
Estrutura de dados com a característica LIFO LIFO: Last-In First-Out
O último a entrar é o primeiro a sair
Funcionamento
O primeiro item inserido na pilha fica no fundo, sendo o último a ser removido
Todos os itens inseridos na pilha são colocados em cima dos itens anteriores
O último item inserido na pilha é o que está no topo, sendo
topo, sendo o primeiro a ser removido
51
Pilhas (Stacks)
Para que serve?
Para modelar situações em que é preciso “guardar para mais tarde” vários elementos, e “lembrar”
sempre do último elemento armazenado (LIFO)
Pilhas (animação)
53 MC-1424 Algoritmos e Estruturas de Dados I - 2° trimestre de 2009
http://www.cosc.canterbury.ac.nz/people/mukundan/dsal/StackAppl.html
Características de Pilhas
Dados somente podem ser colocados no topo da pilha Dados somente podem ser removidos do topo da pilha
Dados somente podem ser removidos do fundo da pilha se existe somente um elemento na pilha
Dados não podem ser removidos do meio da pilha sem antes
remover todos os itens anteriores (do topo)
Operações de uma Pilha
Principais
Empilha (push)
Desempilha (pop)
Auxiliares
Topo (peek)
Vazia (isEmpty)
Cheia (isFull)
Procura (search)
55
Implementação de Pilhas
Lista Estática Seqüencial (Array)
Fácil de implementar
Tamanho limitado
Lista Dinâmica Encadeada
Implementação mais complexa
Sem limitação de tamanho (memória do computador)
Memória alocada dinamicamente
Listas encadeadas que se insere e remove do início
são pilhas
Pilha em Lista Estática Seqüencial
PILHA - lista estática seqüencial que implementa pilha
o elemento 0 será definido como o fundo da pilha
topo da pilha: TOPO é o índice que indica a 1a. posição livre da pilha P
pilha vazia: TOPO = 0
restrição: tamanho máximo
1o. elem.
2o. elem.
3o. elem.
4o. elem.
3
57
3
2
1
0
Pilha em C – Exemplo (1)
#define MAX 50 typedef struct pilha {
int n;
int vet[MAX];
} tipoPilha;
// Prototipos das funcoes tipoPilha *cria(void);
void push(tipoPilha *p, int v), libera(tipoPilha *p);
int pop(tipoPilha *p), vazia(tipoPilha *p);
MC-1424 Algoritmos e Estruturas de Dados I - 2° trimestre de 2009
Pilha em C – Exemplo (1)
// Funcao para criar uma pilha de dados tipoPilha *cria(void){
tipoPilha *p = (tipoPilha*) malloc(sizeof(tipoPilha));
p->n = 0; // Inicializa pilha com zero elementos return p;
}
// empilhamento (push) de elementos void push(tipoPilha *p, int v){
if (p->n == MAX) {
printf("Capacidade da pilha estourou.\n");
exit(1);}
/*Insere elemento na proxima posicao livre*/
p->vet[p->n] = v;
p->n++;
}
59
Pilha em C – Exemplo (1)
// Funcao para desempilhamento (pop) de elementos int pop(tipoPilha *p){
int v;
if (vazia(p)) {
printf("tipoPilha vazia.\n");
return -1;
}
v = p->vet[p->n-1];
p->n--;
return v;
}
// Funcao que verifica se uma pilha esta vazia int vazia(tipoPilha *p){
return (p->n == 0);
}
Pilha em C – Exemplo (1)
/* Funcao que libera espaco em memoria alocado para a pilha */
void libera(tipoPilha *p) {
free(p);
}
61
Topo – agora é um ponteiro para o topo da pilha
Pilha vazia: Topo= NULL
não possui restrição de tamanho máximo
Pilhas em lista encadeada
Pilha em lista encadeada
empilha
desempilha
novo elemento
63
Aplicações de Pilhas
Aplicações diretas
Histórico de páginas visitadas em um navegador Web
Desfazer uma seqüência de ações em um editor de textos (Ctrl+Z)
Realizar cálculos usando a notação polonesa (por exemplo, calculadoras HP)
Chamada de procedimentos em Sistemas Operacionais
Aplicações indiretas
Estrutura de dados auxiliar para algoritmo
Exemplo de aplicação
Calculadora pós-fixada
Notação para expressões aritméticas – infixa = operador entre os operandos (1-2)*(4+5)
pós-fixa = operador após operandos 1 2 – 4 5 + *
pré-fixa = operador antes dos operandos * - 1 2 + 4 5
Exemplo:
calculadora HP científica usa notação pós-fixa
65
Exemplo de aplicação
Calculadora pós-fixada
Avaliação de expressões aritméticas pós-fixadas:
cada operando é empilhado numa pilha de valores
quando se encontra um operador
desempilha-se o número apropriado de operandos
realiza-se a operação devida
empilha-se o resultado
Exemplo:
avaliação da expressão 1 2 – 4 5 + *
Tipo de dados abstratos (TDA)
Tipos abstratos de dados (TAD)
A idéia é encapsular (esconder) de quem usa um determinado tipo a forma concreta com que ele foi implementado
Para isso, separa-se a declaração e a implementação do TAD em dois arquivos:
- NomeDoTAD.h : com a declaração
- NomeDoTAD.c : com a implementação
O programa ou outros TADs que utilizam o seu TAD devem dar um #include no arquivo .h
67
Tipos abstratos de dados (TAD)
Exemplo:
Vamos implementar a estrutura de um TAD em ContaBancaria, com os campos número e saldo onde os clientes podem fazer as seguintes operações:
• Iniciar uma conta com um número e saldo inicial
• Depositar um valor
• Sacar um valor
• Imprimir o saldo
Tipos abstratos de dados (TAD)
ContaBancaria.h
/* definição do tipo */
typedef struct {
int numero;
double saldo;
} ContaBancaria;
/* declaração das funções */
void Inicializa(ContaBancaria* conta, int numero, double saldo);
void Deposito (ContaBancaria* conta, double valor);
void Saque (ContaBancaria* conta, double valor);
void Imprime (ContaBancaria conta);
69
Tipos abstratos de dados (TAD)
ContaBancaria.c
#include <stdio.h>
#include "Contabancaria.h"
void Inicializa(ContaBancaria* conta, int numero, double saldo) {
(*conta).numero = numero;
(*conta).saldo = saldo;
}
void Deposito (ContaBancaria* conta, double valor) {
(*conta).saldo += valor;
}
void Saque (ContaBancaria* conta, double valor) {
(*conta).saldo -= valor;
}
void Imprime (ContaBancaria conta) {
printf("Numero: %d\n", conta.numero);
printf("Saldo: %f\n", conta.saldo);
}
Tipos abstratos de dados (TAD)
int main (int argc, char **argv) {
ContaBancaria conta1;
Inicializa(&conta1, 918556, 300.00);
printf("\nAntes da movimentacao:\n ");
Imprime(conta1);
Deposito(&conta1, 50.00);
Saque(&conta1, 70.00);
printf("\nDepois da movimentacao:\n ");
Imprime (conta1);
}
71
Atividade em aula
Implementar uma TAD para pilha em lista encadeada com as seguintes operações :
1. Criar uma pilha vazia 2. Empilhamento
3. Desempilhamento
4. Imprime a pilha
73
Pilha em C (arquivo pilha.h) – Ex2
typedef struct { int matricula;
char nome[20];
} t_pilha;
void empilha(t_pilha aluno);
t_pilha desempilha();
t_pilha noTopo();
int cheia();
int vazia();
MC-1424 Algoritmos e Estruturas de Dados I - 2° trimestre de 2009
Pilha em C (arquivo pilha.c) –Ex2
#include "pilha.h“
#define TAMMAX 3
#define VAZIA -1 int topo = VAZIA;
t_pilha pilha[TAMMAX];
void empilha(t_pilha aluno){
pilha[++topo] = aluno;
}
t_pilha desempilha() {
return pilha[topo--];
}
t_pilha noTopo() {
return pilha[topo];
}
int cheia() {
return topo+1 ==
TAMMAX;
}
int vazia() { return topo ==
VAZIA;
}
75