Ndia Mendes dos Santos Geraldo Nunes da Silva Jnior Otlio Paulo da Silva Neto
Estrutura de Dados
Ndia Mendes dos Santos Geraldo Nunes da Silva Jnior Otlio Paulo da Silva Neto
Teresina - PI 2013
Instituto Federal de Educao, Cincia e Tecnologia do Piau Este Caderno foi elaborado em parceria entre o Instituto Federal de Educao, Cincia e Tecnologia do Piau e a Universidade Federal de Santa Catarina para a Rede e-Tec Brasil.
Equipe de Elaborao Instituto Federal de Educao, Cincia e Tecnologia do Piau IFPI Coordenao do Curso Thiago Alves Elias da Silva/IFPI Professores-autores Ndia Mendes dos Santos/IFPI Geraldo Nunes da Silva Jnior/IFPI Otlio Paulo da Silva Neto/IFPI Comisso de Acompanhamento e Validao Universidade Federal de Santa Catarina UFSC Coordenao Institucional Araci Hack Catapan/UFSC Coordenao do Projeto Silvia Modesto Nassar/UFSC Coordenao de Design Instrucional Beatriz Helena Dal Molin/UNIOESTE e UFSC Coordenao de Design Grfico Juliana Tonietto/UFSC Design Instrucional Eleonora Schlemper Mendona/UFSC Gustavo Pereira Mateus/UFSC Web Master Rafaela Lunardi Comarella/UFSC Web Design Beatriz Wilges/UFSC Mnica Nassar Machuca/UFSC Diagramao Brbara Zardo/UFSC Roberto Colombo/UFSC Projeto Grfico e-Tec/MEC
e-Tec Brasil
Indicao de cones
Os cones so elementos grficos utilizados para ampliar as formas de linguagem e facilitar a organizao e a leitura hipertextual. Ateno: indica pontos de maior relevncia no texto.
Saiba mais: oferece novas informaes que enriquecem o assunto ou curiosidades e notcias recentes relacionadas ao tema estudado. Glossrio: indica a definio de um termo, palavra ou expresso utilizada no texto. Mdias integradas: sempre que se desejar que os estudantes desenvolvam atividades empregando diferentes mdias: vdeos, filmes, jornais, ambiente AVEA e outras. Atividades de aprendizagem: apresenta atividades em diferentes nveis de aprendizagem para que o estudante possa realiz-las e conferir o seu domnio do tema estudado.
e-Tec Brasil
Sumrio
Palavra do professor-autor Apresentao da disciplina Projeto instrucional Aula 1 Introduo a linguagem de programao C 1.1 Apresentao 1.2 Introduo 1.3 Estrutura bsica de um programa em C 1.5 Viso geral: instrues de entrada e sada 1.6 Fundamentos em C 1.7 Comandos bsicos 1.8 Tipos de dados 1.9 Variveis 1.10 Operadores 1.11 Tomada de deciso 1.12 Laos Aula 2 Funes, matrizes, ponteiros e arquivos 2.1 Funes 2.2 Matrizes 2.3 Ponteiros 2.4 Arquivos Aula 3 Viso geral de estrutura de dados e lista linares 3.1 Introduo 3.2 Conceitos bsicos Aula 4 Pilhas 4.1.Introduo 4.2.Pilha esttica 4.3. Pilha dinmica 9 11 13 15 15 15 17 17 18 19 22 23 25 28 32 37 37 41 43 46 59 59 59 97 97 97 102
e-Tec Brasil
Aula 5 Filas e rvores 5.1 Introduo fila 5.2 Fila esttica 5.3 Fila dinmica 5.4 Introduo rvore 5.5 rvore binria Aula 6 Ordenao e pesquisa 6.1 Introduo ordenao 6.2 Mtodo da bolha ou bubblesort 6.3 Introduo pesquisa 6.4 Pesquisa sequencial 6.4 Pesquisa binria Referncias Currculo dos professores-autores
111 111 113 119 126 128 135 135 136 141 141 144 148 149
e-Tec Brasil
Palavra do professor-autor
Caro estudante! Bem-vindo disciplina de Estrutura de Dados. O objetivo desta disciplina apresentar a Linguagem de Programao C e os seus principais conceitos, bem como uma viso geral acerca de Estrutura de Dados abordando Listas (pilhas, filas) e rvores e uma introduo ordenao de dados, enfocando o Mtodo da Bolha (BubbleSort) e estratgias de pesquisa, especificamente Pesquisa Sequencial e Binria, conceitos, aplicaes e implementaes, na linguagem C. Aproveite o curso e a disciplina, pesquise, troque informaes com seus colegas e tire dvidas com seu tutor, pois ele tem muito mais informaes para compartilhar com voc. Bons estudos!
Professores Ndia Mendes dos Santos Geraldo Nunes da Silva Jnior Otlio Paulo da Silva Neto
e-Tec Brasil
Apresentao da disciplina
As estruturas de dados tm larga aplicao na computao em geral. Sistemas Operacionais e aplicativos as utilizam para vrias atividades importantssimas, como gerenciamento de memria, execuo de processos, armazenamento e gerenciamento de dados no disco, etc. As estruturas de dados definem a organizao, mtodos de acesso e opes de processamento para a informao manipulada pelo programa. A definio da organizao interna de uma estrutura de dados tarefa do projetista da estrutura, que define tambm qual a API para a estrutura, ou seja, qual o conjunto de procedimentos que podem ser usados para manipular os dados na estrutura. esta API que determina a viso funcional da estrutura de dados, que a nica informao relevante para um programador que v utilizar uma estrutura de dados pr-definida. Portanto, no faltam motivos para um estudante da rea ou qualquer desenvolvedor/programador saberem a fundo e com fluncia sobre o assunto.
11
e-Tec Brasil
Projeto instrucional
Disciplina: Estrutura de Dados (carga horria: 90h). Ementa: Estrutura de um programa em C. Constantes e Variveis; Operadores, Expresses e Funes; Entrada e Sada. Estruturas de Controle; Funes e Procedimentos. Vetores e Registros; Ponteiros. Estrutura de Dados do Tipo TADs: Listas Lineares Estticas e Dinmicas. Pilhas Estticas e Dinmicas. Filas Estticas e Dinmicas. rvores: Binrias e Balanceadas. Algoritmos de Percurso. Ordenao e Pesquisa de Dados.
OBJETIVOS DE APRENDIZAGEM
Conhecer e identificar a estrutura bsica de um programa em C. Implementar programas bsicos na linguagem C. Implementar programas em C utilizando as estruturas de deciso e as estrutura em laos. Implementar matrizes, funes na linguagem C. Conceituar e implementar ponteiros. Implementar e classificar os mtodos de manipulao de ponteiros. Conceituar e manipular arquivos. Conceituar Estrutura de Dados. Descrever os tipos de Estrutura de Dados. Implementar as operaes bsicas da Estrutura de Dados do tipo Lista esttica e dinmica de ordenao e desordenao.
AULA
MATERIAIS
Ambiente Virtual de Ensino Aprendizagem (AVEA): http://cefetpi.nucleoead.net/ etapi/; Webconferncia; Ambiente Virtual de Ensino Aprendizagem (AVEA): http://cefetpi.nucleoead.net/ etapi/; Webconferncia; Ambiente Virtual de Ensino Aprendizagem (AVEA): http://cefetpi.nucleoead.net/ etapi/; Webconferncia; Ambiente Virtual de Ensino Aprendizagem (AVEA): http://cefetpi.nucleoead.net/ etapi/; Webconferncia; Ambiente Virtual de Ensino Aprendizagem (AVEA): http://cefetpi.nucleoead.net/ etapi/; Webconferncia; Ambiente Virtual de Ensino Aprendizagem (AVEA): http://cefetpi.nucleoead.net/ etapi/; Webconferncia;
15
15
15
4. Pilhas
Conhecer o funcionamento de uma Pilha. Implementar as operaes bsicas em uma Estrutura Pilha Esttica e dinmica. Conhecer e identificar uma Fila Esttica e Dinmica. Implementar Fila Esttica e Dinmica na linguagem C. Conceituar rvore e rvore Binria; Reconhecer os percursos em rvores binrias. Classificar ou ordenar dados. Implementar o mtodo da Bolha ou BubbleSort. Conceituar e implementar diferentes estratgias de pesquisa.
15
5. Filas e rvores
15
6. Ordenao e pesquisa
15
13
e-Tec Brasil
1.1 Apresentao
Habitualmente antes de resolvermos exemplos ou exerccios, elaboraremos o algoritmo, que nada mais que uma sequncia de operaes cuja execuo produz um resultado que a resposta de um problema proposto. Um programa de computador nada mais que a codificao de um algoritmo numa linguagem de programao. Linguagens como C, Pascal, BASIC, ALGOL, Clipper, COBOL, etc., so chamadas procedurais, devido ao fato das instrues serem executadas de forma sequencial, enquanto que as linguagens baseadas no conceito de eventos como C++, Visual BASIC, Visual Objects, utilizam outra estratgia de programao (Programao Orientada ao Objeto), em C utilizaremos a metodologia estruturada.
1.2 Introduo
A linguagem C foi desenvolvida inicialmente por Dennis M. Ritchie e Ken Tompson no laboratrio Bell no ano de 1972. Baseada na linguagem B criada por Tompson, esta linguagem evoluiu da linguagem BCPL, dando origem as duas linguagens anteriores. C foi inicialmente projetada para ser utilizada no sistema operacional Unix. Podemos definir a linguagem C como sendo uma linguagem de programao robusta e multiplataforma, projetada para aplicaes modulares de rpido acesso.
15
e-Tec Brasil
Veremos aqui a estrutura ANSI C, verso padro definida pelo comit americano ANSI e suportada praticamente por todos os compiladores C.
ANSI a sigla para American National Standards Institute e designa uma organizao americana que tem a funo de estabelecer quais normas desenvolvidas devem virar padro.
Podendo ser considerada como uma linguagem de mdio nvel, pois possui instrues que a tornam ora uma linguagem de alto nvel e estruturada como o Pascal, se assim se fizer necessrio, ora uma linguagem de baixo nvel, pois possui instrues to prximas da mquina, que s o Assembler possui. De fato com a linguagem C podemos construir programas organizados e concisos (como o Pascal), ocupando pouco espao de memria com alta velocidade de execuo (como o Assembler). Infelizmente, dada toda a flexibilidade da linguagem, tambm poderemos escrever programas desorganizados e difceis de serem compreendidos (como usualmente so os programas em BASIC). Devemos lembrar que a linguagem C foi desenvolvida a partir da necessidade de se escrever programas que utilizassem recursos prprios da linguagem de mquina de uma forma mais simples e portvel que o Assembler. Linguagem C case sensitive, ou seja, diferencia letras maisculas de minsculas. As inmeras razes para a escolha da linguagem C como a predileta para os desenvolvedores profissionais. As caractersticas da Linguagem C serviro para mostrar o porqu de sua ampla utilizao.
e-Tec Brasil
16
Estrutura de Dados
1.4.1 Comentrios
Os comentrios servem principalmente para documentao do programa e so ignorados pelo compilador, portanto no iro afetar o programa executvel gerado. Os comentrios iniciam com o smbolo /* e se estendem at aparecer o smbolo */. Um comentrio pode aparecer em qualquer lugar no programa onde possa aparecer um espao em branco e pode se estender por mais de uma linha.
17
e-Tec Brasil
Por ser capaz de manipular bits, bytes e endereos, C se adapta bem a programao em nvel de sistema. E tudo isto realizado por apenas 43 palavras reservadas no Turbo C, 32 nos compiladores padro ANSI e 28 no C Padro. Como curiosidade, o IBM BASIC que um interpretador BASIC com fins puramente educativos tem 159 comandos.
1.6 Fundamentos em C
Desta forma a orientao que adotaremos neste incio do curso se deter mais na compreenso geral do programa, do que a anlise detalhada de cada comando ou funo utilizada. De fato apresentaremos alguns comandos fundamentais para a escrita de programas bsicos e apenas nos utilizaremos sua sintaxe mais elementar (posteriormente estudaremos cada um deles mais detidamente), construiremos os primeiros programas do curso. Exemplo 1: Programa mostra a idade. /* Exemplo Idade */ main ( ) { int idade; idade = 40; printf(Sua idade e %d anos. \n, idade); } Este programa simplesmente imprime Sua idade e 40 anos. saltando uma linha (/n) em seu trmino.
18
Estrutura de Dados
O primeiro caso o mais utilizado. Ele serve para incluir alguns arquivos que contm declarao das funes da biblioteca padro, entre outras coisas. Estes arquivos, normalmente, possuem a extenso .h e se encontram em algum diretrio pr-definido pelo compilador (/usr/include no Linux; c:\dev-c++\include no Windows com o Dev-C++). Sempre que o programa utilizar alguma funo da biblioteca-padro deve ser includo o arquivo correspondente. A tabela a seguir apresenta alguns dos principais . h da linguagem C: Arquivo Descrio stdio.h ->Funes de entrada e sada (I/O) string.h ->Funes de tratamento de strings math.h ->Funes matemticas ctype.h ->Funes de teste e tratamento de caracteres stdlib.h ->Funes de uso genrico A segunda forma, onde o nome do arquivo aparece entre aspas duplas, serve normalmente para incluir algum arquivo que tenha sido criado pelo prprio programador ou por terceiros e que se encontre no diretrio atual, ou seja, no mesmo diretrio do programa que est sendo compilado.
19
e-Tec Brasil
getch ( );
20
Estrutura de Dados
21
e-Tec Brasil
scanf(%s,nome); /* Strings no utilizar & na leitura */ printf(%s sua idade e %d anos. \n, nome, idade); } Faa um programa em C para perguntar sua profisso e mostrar na tela. Poste no AVEA da disciplina o arquivo de sua atividade.
Exemplo: Mesmo nmero com duas representaes diferentes. main ( ) { float a; printf(Digite um numero: );
e-Tec Brasil
22
Estrutura de Dados
1.9 Variveis
As variveis tem uma importncia fundamental na linguagem C. So utilizadas como depsitos temporrios de informaes a serem processados pelo programa escrito na linguagem C.
1.9.1 Variveis
De maneira semelhante as demais linguagens estruturadas, em C as variveis tem seus valores localizados nas rotinas onde foram declaradas (escopo). Todas as variveis devem ser declaradas desta forma: tipo nome_de_variaveis; Exemplos: int i,j,l; short int si; double balanco, consolidacao; char nome[30]; Basicamente, as variveis podem ser declaradas fora das funes (globais) que valem para todas as funes do programa. Podem ser declaradas dentro de uma funo (locais) sendo desconhecida no restante do programa. Alm disso podem ser usadas para passagem de valores entre funes (parmetros).
23
e-Tec Brasil
e-Tec Brasil
24
Estrutura de Dados
1.10 Operadores
C uma das linguagens com maior nmero de operadores, devido possuir todos os operadores comuns de uma linguagem de alto nvel, porm tambm possuindo os operadores mais usuais a linguagens de baixo nvel. Para fins didticos, dividiremos os operadores em aritmticos, lgicos e de bits. No momento abordaremos apenas as duas primeiras classes.
25
e-Tec Brasil
Em C o resultado da comparao ser ZERO se resultar em FALSO e DIFERENTE DE ZERO no caso de obtermos VERDADEIRO num teste qualquer. Programadores experientes utilizam-se desta concluso em alguns programas, onde inexplicavelmente algo testado contra ZERO. Exemplo: Ir calcular a mdia de um aluno sendo que ele possua trs notas, a mdia a soma das notas dividida por trs. #include <stdio.h> #include <conio.h> void main ( ) { clrscr ( ); float nota1; float nota2; float nota3; float media; printf(\n Digite a primeira nota..: ); scanf(%f,¬a1); printf(\n Digite a segunda nota...: ); scanf(%f,¬a2); printf(\n Digite a terceira nota..: ); scanf(%f,¬a3); media=(nota1+nota2+nota3)/3; printf(\n\n Sua mdia ............:%6.2f,media); getch ( ); } Faa um programa em C onde dado 5 nmeros, imprima-os em ordem crescente. Poste no AVEA da disciplina o arquivo de sua atividade.
e-Tec Brasil
26
Estrutura de Dados
O que muda nas operaes a cima, apenas o uso dos incrementos, ps-fixados e prefixados, mas que fazem bastante diferenas quando utilizados em conjunto com outras instrues. Vejamos o exemplo: n = 10; m = ++n printf (\n N=%d M=%d, n, m); a = 10 x = a++ printf(\n A=%d X=%d, a, x);
27
e-Tec Brasil
e-Tec Brasil
28
Estrutura de Dados
A expresso avaliada dever obrigatoriamente estar entre parnteses. Exemplo 2: Maior entre trs nmeros. main ( ) { int a,b,c; clrscr(); printf(Digite o 1 Nmero: ); scanf(%d,&a); printf(\nDigite o 2 Nmero: ); scanf(%d,&b); printf(\nDigite o 3 Nmero: ); scanf(%d,&c); if (a > b) if (a > c) printf(\nO Maior %d,a);
else else
else }
29
e-Tec Brasil
Exemplo 3: Maior entre trs nmeros (segunda soluo). main ( ) { int a,b,c,d; clrscr(); printf(Digite o 1 Nmero: ); scanf(%d,&a); printf(\nDigite o 2 Nmero: ); scanf(%d,&b); printf(\nDigite o 3 Nmero: ); scanf(%d,&c); if (a > b) else if (c > d) else } printf(\nO Maior %d,d); printf(\nO Maior %d,c); d = b; d = a;
e-Tec Brasil
30
Estrutura de Dados
31
e-Tec Brasil
1.12 Laos
Um dos grandes benefcios dos sistemas de processamento de dados est em sua confiabilidade (preciso nos clculos) e rapidez (infinitamente superior ao ser humano), desta forma ideal para processamento de elevado nmero de operaes repetitivas. O processamento de uma Folha de Pagamentos, a Emisso de Notas Fiscais, a Gerao de Estatsticas de Faturamento, so tpicas tarefas a serem realizadas por processamento eletrnico de dados.
e-Tec Brasil
32
Estrutura de Dados
O nmero 2 antes do d causa a representao em vdeo de 2 casas, permitindo o alinhamento da tabuada!. Exerccio1: Elabore tabela de Converso de temperaturas entre as escalas Celsius e Fahrnheit. #include <stdio.h> #include <stdlib.h> main ( ) { int fahr; float celsius; for (fahr = 0; fahr <= 300; fahr = fahr + 20) { printf(%4d, fahr); celsius = (5.0/9.0)*(fahr-32);
printf(\t%6.1f\n,celsius); } } Quando dois ou mais comandos devam ser executados, devemos obrigatoriamente utilizar chaves para delimitar a sequncia de instrues a ser observada.
33
e-Tec Brasil
while (<condio>) { <instruo>; } Exemplo 1: Contagem de 1 a 100 ficaria. main ( ) { int cont=0; while (cont = 100) cont++; printf(%d,cont); }
e-Tec Brasil
34
Estrutura de Dados
int main() { int cont=0; do { cont++; printf(%d ,cont); } while (cont < 100); system(pause); }
Resumo
Nesta aula abordamos conceitos da linguagem de programao C, a sua estrutura bsica de um programao, suas caractersticas, vantagens, desvantagens, operaes, declaraes e manipulaes de variveis e as implementaes das estruturas condicionais, bem como as implementaes de programas das estruturas de lao. Alm de exemplos prticos do nosso dia-a-dia, a fim de um entendimento melhor por parte do leitor aumentando assim seu conhecimento terico.
35
e-Tec Brasil
Atividades de aprendizagem
1. Elabore um programa em C que faa o seguinte: a) Mostre na tela o seu nome. b) Some 10 com 15 e imprima na tela a seguinte frase: O resultado da soma : mostrando o resultado. c) Faa a multiplicao entre 10 e 15 e mostre na tela o resultado. d) Pergunte o seu nome e imprima na tela. e) Pergunte o nome da pessoa e o sobrenome e imprimir os mesmos. f) Leia dois nmeros e apresente seu produto. g) Leia dois nmeros e apresenta a sua subtrao. h) Leia o nome e as duas notas de um aluno e apresente ambos na tela.
e-Tec Brasil
36
Estrutura de Dados
2.1 Funes
Conceitualmente, C baseada em blocos de construo. Assim sendo, um programa em C nada mais que um conjunto de funes bsicas ordenadas pelo programador. As instrues printf( ) e scanf( ), vistas anteriormente, no fazem parte do conjunto de palavras padres da linguagem (instrues), pois no passam elas mesmas de funes escritas em C! Esta abordagem permite a portabilidade da linguagem, pois seus comandos de entaada e sada, no so parte do conjunto bsico da linguagem, livrando-a desta forma dos problemas de suporte aos diversos padres de vdeos, teclados e sistemas operacionais existentes. Cada funo C na verdade uma sub-rotina que contm um ou mais comandos em C e que executa uma ou mais tarefas. Em um programa bem escrito, cada funo deve executar uma tarefa. Esta funo dever possuir um nome e a lista de argumentos que receber. As funes em C so muito semelhantes s usadas no Pascal, com a diferena que o prprio programa principal apenas uma funo que se inicia com a palavra reservada main ( ) podendo receber parmetros diretamente do DOS, por exemplo. Exemplo: Programa principal chamando funo alo. main ( ) { } alo ( );
37
e-Tec Brasil
alo ( ) { printf (Al!\n\n); } Retomemos o exemplo do clculo de um nmero elevado ao quadrado. Exemplo: Quadrado com funo. main ( ) { int num; printf(Digite um numero: ); scanf(%d,&num); sqr(num); /* sqr recebe num do programa principal */ } sqr ( ) { } O argumento simplesmente o valor (em num) digitado no programa principal (em scanf) e enviado a funo sqr. Um conceito importante e normalmente confundido a diferena conceitual entre argumento e parmetro que em resumo pode ser definido da seguinte forma: Argumento se refere ao valor que usado para chamar uma funo. O termo Parmetro se refere varivel em uma funo que recebe o valor dos argumentos usados na funo. A distino que deve ser compreendida que a varivel usada como argumento na chamada de uma funo no tem nenhuma relao com o parmetro formal que recebe o valor dessa varivel. int x; /* x um parmetro recebido do programa principal no caso x vale o contedo de num */ printf(%d ao quadrado e %d ,x,x*x);
e-Tec Brasil
38
Estrutura de Dados
Exerccio: Passagem de variveis entre rotinas. int x; main ( ) { int a; printf(Digite um valor: ); scanf(%d,&a); x = 2 * a + 3; printf(%d e %d,x,soma(a)); } soma (z) { int z; x = 2 * x + z;
return(x); }
39
e-Tec Brasil
#include <stdio.h> #include <stdlib.h> int sqr (int); /* prottipo da funo*/ int main ( ) { int num; printf(Digite um numero: ); scanf(%d,&num); sqr(num); /* sqr recebe num do programa principal */ system(pause); } int sqr(int num) { int x = num; /* x um parmetro recebido do programa principal no caso x vale o contedo de num */ printf(%d ao quadrado e %d \n,x,x*x); }
e-Tec Brasil
40
Estrutura de Dados
printf(Digite um numero ou negativo p/ sair \n); scanf(%d,&n); if (n < 0) { break; } printf(O Fatorial de %d eh %d \n,n,fatorial(n)); } while (1); system(pause); return 0; } long fatorial (int n) { return ((n==0) ? (long)1 : (long)n * fatorial(n-1) ); }
2.2 Matrizes
Uma Matriz um conjunto de variveis de mesmo tipo que compartilham um mesmo nome. Com Matriz agora podemos armazenar mais de um valor para depois serem manipulados atravs de um ndice, o qual referencia cada um dos elementos, para se criar uma Matriz necessrio definir um tipo, seu nome e quantidade de elementos, sedo este ultimo entre colchetes ([ ]). Vejamos agora a declarao de uma matriz. int mat[5];
41
e-Tec Brasil
Vejamos um exemplo para se referenciar um elemento da Matriz: x = mat[10]; /* x recebe o elemento de mat na posio 10 */ mat[10] = 20; /* o elemento de mat na posio 10 recebe o valor 20 */
e-Tec Brasil
42
Estrutura de Dados
2.3 Ponteiros
O ponteiro nada mais do que uma varivel que guarda o endereo de outra varivel.
O ponteiro pode ser declarado para qualquer tipo legal de varivel em C (char,int,float,double, etc), alm devoid, que seria um genrico, podendo apontar para qualquer tipo de dado.
43
e-Tec Brasil
52
53 40
.......
4052 ptr
40
.......
10 var
40
54
.......
int var; int *ptr; var = 10; ptr = &var; Na sequncia acima, so declarados uma varivel tipo int (var) e um ponteiro para o mesmo tipo (ptr). A terceira linha atribui o valor 10 a var e a ltima linha inicializa o ponteiro ptr. Observa-se o uso do operador de endereamento (&) para inicializao do ponteiro. Isso significa, no cdigo ptr = &var, que ptr passa a conter o endereo de var, no o seu valor. Supondo que o sistema endereado por 2 bytes, a Figura 2.1 acima d uma ideia grfica dessa associao: o contedo de ptr 4052, que o endereo do primeiro byte da varivel var (ptr ocupa 2 bytes por causa do endereamento do sistema e var tambm ocupa 2 bytes, mas por ser do tipo int. O valor 4052 para a posio de memria de var apenas ilustrativo. Na prtica, depender do local de memria onde o programa foi carregado. Com ptr apontando para var, possvel realizar operaes com esta ltima de forma indireta, a partir de ptr. Exemplos a seguir. Acrescentando a linha int newVar = *ptr; ao cdigo anterior, o valor de newVar 10, que o valor de var lido indiretamente atravs de ptr.
e-Tec Brasil
44
Estrutura de Dados
E a linha *ptr = 20; modifica o valor de var para 20, ou seja, altera de forma indireta atravs de ptr. importante lembrar que um ponteiro declarado e no inicializado poder ter contedo nulo ou aleatrio, a depender da alocao sistema. Nessa condio, se o contedo apontado for modificado, algumas posies de memria tero seus valores indevidamente alterados e as consequncias sero imprevisveis. Agora veremos um exemplo completo de utilizao de ponteiros: #include <stdio.h> #include <stdlib.h> int main ( ) { int a; int b; int c; int *ptr; /* declara um ponteiro para um inteiro */ /* um ponteiro para uma varivel do tipo inteiro */ a = 100; b = 2; c = 3; ptr = &a; /* ptr recebe o endereo da varivel a */ printf(Valor de ptr: %p, Contedo de ptr: %d\n, ptr, *ptr); printf(B: %d, C: %d \n, b, c); a = 200; printf(Valor de ptr: %p, Contedo de ptr: %d\n, ptr, *ptr); system(pause); }
45
e-Tec Brasil
Escreva um resumo sobre ponteiros. Poste no AVEA da disciplina o arquivo de sua atividade.
2.4 Arquivos
Um arquivo pode ser visto de duas maneiras, na maioria dos sistemas operacionais: em modo texto, como um texto composto de uma sequncia de caracteres, ou em modo binrio, como uma sequncia de bytes (nmeros binrios). Podemos optar por salvar (e recuperar) informaes em disco usando um dos dois modos, texto ou binrio. Uma vantagem do arquivo texto que pode ser lido por uma pessoa e editado com editores de textos convencionais. Em contrapartida, com o uso de um arquivo binrio possvel salvar (e recuperar) grandes quantidades de informao de forma bastante eficiente. O sistema operacional pode tratar arquivos texto de maneira diferente da utilizada para tratar arquivos binrios. Em casos especiais, pode ser interessante tratar arquivos de um tipo como se fossem do outro, tomando os cuidados apropriados.
FILE um tipo definido pela biblioteca padro que representa uma abstrao do arquivo.
e-Tec Brasil
46
Estrutura de Dados
Se o arquivo j existe e solicitamos a sua abertura para escrita com modo w, o arquivo apagado e um novo, inicialmente vazio, criado. Quando solicitamos com modo a, o mesmo preservado e novos contedos podem ser escritos no seu fim. Com ambos os modos, se o arquivo no existe, um novo criado. Os modos b e t podem ser combinados com os demais. Maiores detalhes e outros modos de abertura de arquivos podem ser encontrados nos manuais da linguagem C. Em geral, quando abrimos um arquivo, testamos o sucesso da abertura antes de qualquer outra operao, por exemplo:
47
e-Tec Brasil
avana, passando a apontar para o prximo dado do arquivo (que pode ser capturado numa leitura subsequente). O prottipo da funo fscanf : int fscanf (FILE* fp, char* formato, ...); Conforme pode ser observado, o primeiro parmetro deve ser o ponteiro do arquivo do qual os dados sero lidos. Os demais parmetros so os j discutidos para a funo scanf: o formato e a lista de endereos de variveis que armazenaro os valores lidos. Como a funo scanf, a funo scanf tambm tem como valor de retorno o nmero de dados lidos com sucesso. Uma outra funo de leitura muito usada em modo texto a funo fgetc que, dado o ponteiro do arquivo, captura o prximo caractere do arquivo. O prottipo dessa funo : int fgetc (FILE* fp); Apesar do tipo do valor de retorno ser int, o valor retornado o caractere lido. Se o fim do arquivo for alcanado, a constante EOF (end of file) retornada. Outra funo muito utilizada para ler linhas de um arquivo a funo fgets. Essa funo recebe como parmetros trs valores: a cadeia de caracteres que armazenar o contedo lido do arquivo, o nmero mximo de caracteres que deve ser lido e o ponteiro do arquivo. O prottipo da funo : char* fgets (char* s, int n, FILE* fp); A funo l do arquivo uma sequncia de caracteres, at que um caractere \n seja encontrado ou que o mximo de caracteres especificado seja alcanado. A especificao de um nmero mximo de caracteres importante para evitarmos que se invada memria quando a linha do arquivo for maior do que supnhamos. Assim, se dimensionarmos nossa cadeia de caracteres, que receber o contedo da linha lida, com 121 caracteres, passaremos esse valor para a funo, que ler no mximo 120 caracteres, pois o ltimo ser ocupado pelo finalizador de string o caractere \0. O valor de retorno dessa funo o ponteiro da prpria cadeia de caracteres passada como parmetro ou NULL no caso de ocorrer erro de leitura (por exemplo, quando alcanar o final do arquivo).
e-Tec Brasil
48
Estrutura de Dados
49
e-Tec Brasil
e-Tec Brasil
50
Estrutura de Dados
/* Converte arquivo para maisculas */ #include <stdio.h> #include <ctype.h> /* funo toupper */
int main (void) { int c; char entrada[121]; /* armazena nome do arquivo de entrada */ char saida[121]; /* armazena nome do arquivo de sada */ FILE* e; /* ponteiro do arquivo de entrada */ FILE* s; /* ponteiro do arquivo de sada */ /* pede ao usurio os nomes dos arquivos */ printf(Digite o nome do arquivo de entrada: ); scanf(%120s,entrada); printf(Digite o nome do arquivo de saida: ); scanf(%120s,saida); /* abre arquivos para leitura e para escrita */ e = fopen(entrada,rt); if (e == NULL) { printf(No foi possvel abrir arquivo de entrada.\n); return 1; } s = fopen(saida,wt); if (s == NULL) { printf(No foi possvel abrir arquivo de saida.\n); fclose(e); return 1; }
51
e-Tec Brasil
/* l da entrada e escreve na sada */ while ((c = fgetc(e)) != EOF) fputc(toupper(c),s); /* fecha arquivos */ fclose(e); fclose(s); return 0; }
52
Estrutura de Dados
FILE* fp; /* ponteiro do arquivo de entrada */ /* pede ao usurio o nome do arquivo e a sub-cadeia */ printf(Digite o nome do arquivo de entrada: ); scanf(%120s,entrada); printf(Digite a sub-cadeia: ); scanf(%120s,subcadeia); /* abre arquivos para leitura */ fp = fopen(entrada,rt); if (fp == NULL) { printf(No foi possvel abrir arquivo de entrada.\n); return 1; } /* l linha a linha */ while (fgets(linha,121,fp) != NULL) { n++; if (strstr(linha,subcadeia) != NULL) { achou = 1; break; } } /* fecha arquivo */ fclose(fp); /* exibe sada */ if (achou) printf(Achou na linha %d.\n, n); else printf(Nao achou.); return 0;
Aula 2 Funes, matrizes, ponteiros e arquivos
53
e-Tec Brasil
...
FILE* fp; char palavra[121]; ... while (fscanf(fp,%120s,palavra) == 1) { if (strcmp(palavra,RETANGULO)==0) { /* interpreta retngulo */
} else
} else
e-Tec Brasil
54
Estrutura de Dados
} }
55
e-Tec Brasil
struct ponto { float x, y, z; }; typedef struct ponto Ponto; Uma funo para salvar o contedo de um vetor de pontos pode receber como parmetros o nome do arquivo, o nmero de pontos no vetor, e o ponteiro para o vetor. Uma possvel implementao dessa funo ilustrada abaixo:
void salva (char* arquivo, int n, Ponto* vet) { FILE* fp = fopen(arquivo,wb); if (fp==NULL) { printf(Erro na abertura do arquivo.\n); exit(1);
} fwrite(vet,sizeof(Ponto),n,fp); fclose(fp); }
A rigor, os tipos int so substitudos pelo tipo size_t, definido pela biblioteca padro, sendo, em geral, sinnimo para um inteiro sem sinal (unsigned int).
Assista video-aula da disciplina de Estrutura de Dados disponvel em http://cefetpi.nucleoead.net/ etapi/. Aproveite para revisar os contedos da aula sobre Funes, Matrizes, Ponteiros e Arquivos.
Resumo
Nesta aula abordamos as principais implementaes da linguagem de programao C, aprendemos ainda como criar funes ou sub-rotinas, a manipulao de matrizes, a implementao de programas utilizando ponteiros. Por fim, aprendemos a criar novos tipo de dados implementado registro e manipulando arquivos. Alm de exemplos prticos do nosso dia-a-dia, a fim de disponibilizar ao leitor um excelente embasamento terico.
e-Tec Brasil
56
Estrutura de Dados
Atividades de aprendizagem
1. Fazer um programa que calcule o volume de uma esfera, sendo que o volume de uma esfera raio*raio*raio. Crie uma funo que faa esse clculo. 2. Elabore programa que leia n nmeros digitados e apresente sua mdia. 3. Com base no estudo de Ponteiros, qual das opes a baixo correto afirmar? a) Ponteiro uma varivel que armazena endereo. b) Ponteiro o valor de uma varivel. c) Ponteiro o indicador da prxima varivel a ser passada. d) Ponteiro o endereo que aponta para uma varivel. 4. Quais das seguintes instrues declaram um ponteiro para uma varivel float? a) Float p b) Float *p c) *Float p d) Float* p 5. O seguinte programa est correto? Justifique. #include <stdio.h> const int VAL=123; int main() { } int *p = VAL; printf(%d \n, *p); return 0;
57
e-Tec Brasil
3.1 Introduo
Em um projeto de software, existem dois aspectos que devem ser estudados: os procedimentos que devem ser previstos pelo software e sobre que dados estes procedimentos iro atuar. Nas tcnicas estruturadas de projeto de software era dada nfase aos procedimentos, com a identificao dos aspectos funcionais na primeira etapa de desenvolvimento do software. Com as tcnicas para especificao dos dados a nvel conceitual, a importncia dos procedimentos e dados tornou-se equilibrada. Atualmente, j existem tcnicas de programao com nfase nos dados (programao baseada em objetos). Mas, independentemente das tcnicas de anlise e programao utilizadas, programas precisam manipular dados e extremamente importante o conhecimento de conceitos e detalhes da implementao das diversas estruturas de dados que manipulam estes dados. Neste texto, inicialmente, alguns conceitos bsicos so apresentados. A seguir, so descritas as principais Estruturas de Dados, com seus respectivos algoritmos.
59
e-Tec Brasil
e-Tec Brasil
60
Estrutura de Dados
I. Quantos bytes devem ser reservados para armazenar esta varivel (Ex.: no caso de uma varivel inteira, deve ser reservado um espao que garanta que o maior inteiro permitido poder ser representado). II. Como estes bytes devem ser interpretados (Ex.: uma cadeia de bits pode ser interpretada como um inteiro ou um real). Assim, tipos de dados podem ser vistos como mtodos para interpretar o contedo da memria do computador.
61
e-Tec Brasil
diretamente do conhecimento de algoritmos para manipular a estrutura de maneira eficiente. As estruturas de dados de tipos de dados estruturadas se dividem em homogneos (vetores e matrizes) e heterogneos (registros). As estruturas homogneas so conjuntos de dados formados pelo mesmo tipo de dado primitivo. E as estruturas heterogneas so conjuntos de dados formados por tipos de dados primitivos diferentes (campos do registro) em uma mesma estrutura. A escolha de uma estrutura de dados apropriada pode tornar um problema complicado em um de soluo bastante trivial. O estudo das estruturas de dados est em constante desenvolvimento (assim como o de algoritmos), mas, apesar disso, existem certas estruturas clssicas que se comportam como padres. Estruturas de dados clssicas: I. Lista. II. Pilha. III. Fila. IV. rvores. Nas prximas sees sero apresentados as principais Estruturas de Dados utilizadas para representar listas, pilhas, filas e rvores. Alm disso, sero apresentados os algoritmos que devem ser utilizados para manipular estas estruturas.
e-Tec Brasil
62
Estrutura de Dados
Sabemos que antes de executar um programa, o computador precisa carregar seu cdigo executvel para a memria. Da rea de memria que reservada para o programa, uma parte usada para armazenar as instrues a serem executadas e a outra destinada ao armazenamento dos dados. Quem determina quanto de memria ser usado para as instrues o compilador. Alocar rea para armazenamento de dados, entretanto, responsabilidade do programador. Uma lista linear pode ser implementada usando vetores ou ponteiros. Se for implementada usando vetores, deve estipular qual a quantidade de elementos que a lista pode armazenar. A memria para armazenamento dos dados alocada em tempo de compilao. Quando implementada usando ponteiros, a memria alocada conforme novos elementos so colocados na lista e desalocada quando elementos so retirados. Ou seja, vai alocando memria dinamicamente, em tempo de execuo.
63
e-Tec Brasil
Operaes bsicas I. Inserir elemento A Figura 3.1 ilustra a insero de trs elementos em uma lista esttica desordenada. Inicialmente o vetor est vazio. O primeiro elemento a chegar o aluno Jos com matrcula 256. Este ser colocado na primeira posio do vetor.
Vetor Vazio
256/ Jos 132/ Ana 429/ Paulo
1
256/ Jos
2
132/ Ana
1
256/ Jos
2
132/ Ana
Posteriormente, chegam mais dois alunos (Ana com matrcula 132 e Paulo com matrcula 429), que so colocados nas prximas posies disponveis do vetor (posio 2 e posio 3). Quando uma insero vai ser executada, necessrio verificar se o vetor tem posies disponveis. Caso contrrio, a insero no pode ser efetuada. O cdigo abaixo, implementado est em linguagem C, inserir um novo aluno lista: //Inserir novo aluno void inserir() { int cont; do{ cabec();
e-Tec Brasil
64
Estrutura de Dados
printf(\nInserir Novo Aluno\n\n); if (qa < maximo) { // verifica se o vetor pode receber novo aluno printf(\nMatricula do Aluno: ); scanf(%d,&turma[qa].mat); printf(\nNome: ); fflush(stdin); gets(turma[qa].nome); printf(\nPolo: ); scanf(%s,&turma[qa].polo); qa++; printf(\n\nAluno Inserido com Sucesso!!!\n\n); } else { // vetor cheio printf(\n\n\aNao Pode Inserir - Turma Cheia!!!\n\n); getche(); break; } printf(\n\nInserir outro(1-sim/2-nao)? ); scanf(%d,&cont); }while (cont == 1); } II. Consultar elemento Depois que um elemento inserido, a operao mais executada a consulta. Para a consulta necessrio saber qual elemento deseja consultar. Neste caso faremos uma consulta por matrcula. Para isso, a matrcula do aluno a ser consultado deve ser lida. feita uma pesquisa em todas as posies ocupadas do vetor, a procura do elemento.
65
e-Tec Brasil
Vetor
256/ Jos 132/ Ana 429/ Paulo 578/ Maria 527/ Joo 514/ Sara
No vetor da Figura 3.2 temos seis elementos. Vamos consultar o elemento de matrcula 578. Para encontr-lo, temos que varrer o vetor desde o seu incio e paramos na posio 4 que a posio onde ele se encontra. Caso quisssemos consultar o elemento de matrcula 192, iramos varrer todo o vetor, elemento a elemento e ao chegar na sexta posio (que a ultima) ficaramos sabendo que este elemento no se encontra no vetor. Quando um elemento encontrado, seus dados so apresentados e quando ele no est no vetor, uma mensagem de erro deve ser dada ao usurio. O cdigo abaixo, implementado est em linguagem C, realiza um consulta de um determinado aluno: //Consultar aluno cadastrado por matricula void consultarmat() { int i, matcon, achou, cont; do { cabec(); printf(\nConsultar Aluno por Matricula\n\n); printf(\nMatricula do Aluno: ); scanf(%d,&matcon); achou = procura(matcon); if (achou != -1) mostre(achou); else // aluno nao foi encontrado printf(\n\n\aNumero de Matricula Incorreto!!!!!!\n); printf(\n\nConsultar outro(1-sim/2-nao)? ); scanf(%d,&cont); } while (cont == 1); }
e-Tec Brasil
66
Estrutura de Dados
III. Remover elemento Caso um elemento no precise mais fazer parte da estrutura, ele pode ser removido. Para remover os dados de um elemento necessrio saber qual elemento deseja remover. J que iremos Neste caso faremos a busca por matrcula. Para isso, a matrcula do aluno a ser removido deve ser lida. feita uma pesquisa em todas as posies ocupadas do vetor, a procura da matrcula. Assim que o elemento encontrado, seus dados devem ser apresentados ao usurio (neste caso a matrcula e o nome). Dessa forma ele pode verificar se realmente aquele o elemento a ser removido. Quando o elemento no encontrado, uma mensagem de erro deve ser dada ao usurio. Numa lista desordenada, para a remoo ser efetuada, o ltimo elemento do vetor deve ser transferido para a posio do elemento removido, conforme Figura 3.3 a seguir.
Vetor antes da Remoo
256/ Jos 132/ Ana 429/ Paulo 578/ Maria 127/ Joo 314/ Sara
256/ Jos
132/ Ana
429/ Paulo
578/ Maria
127/ Joo
314/ Sara
O cdigo abaixo, implementado est em linguagem C, realiza uma remoo aluno: //Remover aluno cadastrado void remover() { int matrem, i, cont, achou, conrem; do{ cabec(); printf(\nRemover Aluno\n\n);
67
e-Tec Brasil
printf(\nMatricula do Aluno: ); scanf(%d,&matrem); achou = procura(matrem); if (achou != -1) { mostre(achou); printf(\nDeseja remover o aluno (1-sim/2-nao)? ); scanf(%d,&conrem); if (conrem==1) { // verifica se quer remover turma[i]= turma[qa-1]; qa--; printf(\n\nAluno removido com Sucesso!!!\n); } else printf(\n\n\aO aluno nao foi removido!!!\n); break; } else // aluno nao foi encontrado printf(\n\naNumero de Matricula Incorreto!!!!!!\n); printf(\n\nRemover outro(1-sim/2-nao)? ); scanf(%d,&cont); }while (cont == 1); } IV. Listagem de todos os elementos A operao de listagem possibilita a visualizao dos dados de todos os elementos cadastrados. feita uma varredura no vetor e todos os dados de todos os elementos so apresentados ao usurio. Caso a lista esteja vazia, ser apresentada uma mensagem. O cdigo abaixo representa a impresso de todos os elementos:
e-Tec Brasil
68
Estrutura de Dados
//Imprimir relatrio com as informaes de todos alunos void listagem() { int i; cabec(); printf(\nRelatorio Geral\n); printf(\n\nMatricula Aluno Polo ); printf(\n---------------------------------------------); for(i = 0; i < qa; i++) printf(\n%9d %-20s %-10s, turma[i].mat, turma[i].nome, turma[i].polo); printf(\n---------------------------------------------); printf(\n\nDigite qualquer tecla para sair... ); getche(); }
A implementao do cdigo completo de lista esttica desordenada na linguagem C estar disponibilizado no AVEA em formatos .pdf e .cpp! b) Lista esttica ordenada Nesse tipo de lista, os elementos devem ser colocados na estrutura obedecendo a uma ordenao. Qualquer operao feita na estrutura, no pode afetar na ordenao da mesma. A vantagem dessa lista ser notada principalmente nos momentos que necessite percorrer a lista a procura de algum elemento. Aqui, o programa anterior ser modificado, fazendo com que os alunos sejam armazenados no vetor por ordem de matrcula. Esta estrutura implementada usando vetores e se preocupa com ordenao. Os elementos so colocados na estrutura usando uma funo procurando a posio correta de insero na ordem crescente. Nas prximas sees ser descrita cada uma das operaes feitas nesta estrutura. No exemplo, teremos uma lista com os dados dos alunos de uma turma (para simplificar, cada aluno tem apenas a matrcula, nome e seu polo).
Aula 3 Viso geral de estrutura de dados e lista linares
69
e-Tec Brasil
Operaes bsicas I. Inserir elemento Para inserir um elemento em uma lista ordenada podem ocorrer cinco possibilidades: I. A lista est cheia: nesse caso a insero cancelada. II. A lista est vazia: o elemento colocado na primeira posio do vetor. III. O elemento a ser inserido menor do que o primeiro da lista. IV. O elemento a ser inserido maior do que o ultimo da lista. V. O elemento novo ser inserido entre elementos da lista. A Figura 3.4 ilustra a insero de quatro elementos em uma lista esttica ordenada. Inicialmente o vetor est vazio e o primeiro elemento a chegar o aluno Jos com matrcula 256, conforme a Figura 3.4a e est insero ser colocada na primeira posio do vetor. Posteriormente, conforme Figura 34.b, chega Ana com matrcula 132. Para que a lista fique ordenada, deve verificar em qual posio o elemento deve ser inserido. Nesse caso, a matrcula 132 menor que 256 (que a primeira da lista). Assim, todos os elementos a partir da posio onde o elemento de matrcula 256 se encontra, devem se deslocar uma posio, abrindo espao para o elemento ser inserido. Agora de acordo com a Figura 3.4c chega o elemento de matrcula 429. Esta matrcula maior do que todas as matrculas do vetor, portanto, ele inserido no final do vetor, sem necessidade de deslocamentos. E por final, chega o elemento de matrcula 197 que ser inserido no espao conformeFigura 3.4d. Devemos descobrir onde se encontra o primeiro elemento maior do que o que ser inserido, ou seja, seu sucessor imediato. Neste caso, ele deve entrar na posio do elemento de matrcula 256. O espao deve ser liberado, fazendo-se necessrio o deslocamento de todos os elementos a partir do elemento de matrcula 256. A principal questo da insero ordenada descobrir o local onde o elemento deve ser inserido e, se necessrio, fazer os deslocamentos.
e-Tec Brasil
70
Estrutura de Dados
Vetor Vazio
1
256/ Jos
1
132/ Ana
2
256/ Jos
1
132/ Ana
2
197/ Maria
3
256/ Jos
4
429/ Paulo
71
e-Tec Brasil
// Inserir um novo aluno na escola void inserir() { int cont; do{ cabec(); printf(\nInserir Novo Aluno\n); if (qa < maximo) { // verifica se o vetor pode receber novo aluno printf(\nMatricula do Aluno: ); scanf(%d,&al.mat); printf(\nNome: ); fflush(stdin); gets(al.nome); printf(\nPolo: ); scanf(%s,&al.polo); colocarordem(); qa++; printf(\n\nAluno Inserido com Sucesso!!!\n); } else { // vetor cheio printf(\n\n\aNao Pode Inserir - Turma Cheia!!!\n); getche(); break; } printf(\n\nContinuar inserindo aluno (1-sim/2-nao)? ); scanf(%d,&cont); }while (cont == 1); }
e-Tec Brasil
72
Estrutura de Dados
II. Consultar elemento Na Figura 3.5 a matrcula do aluno a ser consultado deve ser lida. feita uma varredura em todas as posies ocupadas do vetor, a procura da matrcula. No caso de uma lista ordenada, se estivssemos procurando um aluno de matrcula 120, assim que fizssemos a leitura da primeira matrcula do vetor, j saberamos que a matrcula 120 no est no vetor, evitando uma varredura at o final do vetor. Na estrutura ordenada, as consultas so mais eficientes.
Vetor
132/ Ana 578/ Maria 256/ Jos 429/ Paulo 527/ Joo 514/ Sara
O cdigo abaixo, implementado est em linguagem C, realiza um consulta de um determinado aluno: //Consultar um aluno da escola void consultar() { int matcon, achou, continuar; do{ cabec(); printf(\nConsultar Aluno\n\n); printf(\nMatricula do Aluno: ); scanf(%d,&matcon); achou = procura(matcon); if (achou!=-1) mostre(achou); else printf(\n\n\aNumero de Matricula Incorreto!!!!!!\n);
73
e-Tec Brasil
printf(\n\nContinuar consultando aluno(1-sim/2-nao)? ); scanf(%d,&continuar); }while (continuar == 1); } III. Remover elemento Comeamos com a leitura da matrcula do aluno a ser removido. feita uma varredura em todas as posies ocupadas do vetor, a procura da matrcula. Assim que o elemento encontrado, seus dados devem ser apresentados ao usurio (neste caso a matrcula e o nome). Dessa forma ele pode verificar se realmente aquele o elemento a ser removido. Quando o elemento no encontrado, uma mensagem de erro deve ser dada ao usurio. No exemplo da Figura 3.6 a seguir, desejamos remover o elemento de matrcula 256. Para que a lista fique contnua e ordenada, todos os elementos que vem depois do elemento que ser removido, devem ser trazidos uma posio a frente.
Vetor antes da Remoo
132/ Ana 197/ Maria 256/ Jos 429/ Paulo 527/ Joo 714/ Sara
132/ Ana
197/ Maria
256/ Jos
429/ Paulo
527/ Joo
714/ Sara
1
132/ Ana
2
197/ Maria
3
429/ Paulo
4
527/ Joo
5
714/ Sara
e-Tec Brasil
74
Estrutura de Dados
// Remover um aluno da escola void remover() { int matrem, i, achou, continuar, conrem; do{ cabec(); printf(\nRemover Aluno\n\n); printf(\nMatricula do Aluno: ); scanf(%d,&matrem); achou = procura(matrem); if (achou!=-1) { mostre(achou); printf(\nDeseja remover o aluno (1-sim/2-nao)? ); scanf(%d,&conrem); if (conrem == 1) { for (i=achou;i<qa;i++) turma[i]=turma[i+1]; qa--; printf(\n\nAluno removido com Sucesso!!!\n); } else printf(\n\n\aO aluno nao foi removido!!!\n); } else printf(\n\n\aNumero de Matricula Incorreto!!!!!!\n); printf(\n\nContinuar removendo aluno (1-sim/2-nao)? );
75
e-Tec Brasil
scanf(%d,&continuar); }while (continuar == 1); } IV. Listagem de todos os elementos A operao de listagem possibilita a visualizao dos dados de todos os elementos cadastrados. feita uma varredura no vetor e todos os dados de todos os elementos so apresentados ao usurio. O cdigo abaixo representa a impresso de todos os elementos: //Imprimir o relatorio contendo os dados de todos os alunos void listagem() { int i; float soma=0; cabec(); printf(\nRelatorio Geral\n); printf(\nMatricula Aluno Polo); printf(\n--------------------------------------------); for(i = 0; i<qa; i++) printf(\n%9d %-20s %-10s, turma[i].mat, turma[i].nome, turma[i]. polo); printf(\n--------------------------------------------); printf(\n\nDigite qualquer tecla para sair); getch(); }
A implementao do cdigo completo de lista esttica ordenada na linguagem C estar disponibilizado junto a plataforma AVEA em formatos .pdf e .cpp!
e-Tec Brasil
76
Estrutura de Dados
Vamos praticar, atravs do cdigo completo do contedo visto at o momento da aula 3 disponvel no AVEA, implemente um novo programa trocando variveis alunos, matricula e polo por pessoa, rg e endereo. c) Lista dinmica desordenada Esta lista implementada usando ponteiros. A memria para armazenar os dados alocada em tempo de execuo. Na prxima seo ser descrito o funcionamento de cada uma das operaes bsicas. O referido programa faz o cadastro dos alunos de uma turma em uma lista usando ponteiros. Esta lista possui dois ponteiros, um que guarda o endereo do primeiro elemento da lista (inicio) e outro que guarda o endereo do ltimo elemento da lista (fim). Operaes bsicas I. Inserir elemento A Figura 3.7 ilustra a insero de trs elementos em uma lista dinmica desordenada. Inicialmente a lista est vazia, portanto o valor do ponteiro inicio e fim NULL (passo 1). Quando um elemento vai ser inserido, a memria alocada e os dados so armazenados (passo 2). Todo n criado em uma lista dinmica desordenada, no tem vizinho seguinte, por isso ele aponta para NULL. Na insero do primeiro elemento, os ponteiros inicio e fim apontam para este elemento (no exemplo, endereo 1010).
INCIO FIM INCIO FIM INCIO FIM
1010
NULL
10/Ana
22/Jlia
1010
1040
NULL
INCIO FIM
10/Ana
22/Jlia
17/Paulo
1010
1040
1080
NULL
77
e-Tec Brasil
No (passo 3) temos a chegada de um outro elemento. A memria alocada e o novo n tem os dados preenchidos e tem que ser anexado aos outros ns da lista. Todo n que chega aponta para NULL e o ponteiro fim passa a ter o endereo do n que acabou de chegar. O n que anteriormente era o ltimo da lista (1010) passar a ter como vizinho o n que acabou de chegar (ou seja, aponta para 1040). O (passo 4) mostra uma outra insero de n. Veja que a cada novo elemento, apenas o endereo do ponteiro fim modificado. O ponteiro inicio permanece com o mesmo valor. O cdigo abaixo, implementado est em linguagem C, insere um novo aluno lista: /* Funcao para inserir um novo no, ao final da lista */ void inserir () { TAluno *novono; int i, matl, continuar; char nomel[20]; do{ cabec(); printf(\n Inserir novo aluno \n); printf(\n Matricula: ); scanf(%d,&matl); printf(\n Nome: ); fflush(stdin); gets(nomel); fflush(stdin); qa++;
e-Tec Brasil
78
Estrutura de Dados
//Aloca memoria para o novo aluno e coloca os dados novono = (TAluno *)malloc(sizeof(TAluno)); novono->mat = matl; for (i=0;i<=19;i++) novono->nome[i] =nomel[i]; novono->prox = NULL; // Inserir novono na lista de alunos if (inicio == NULL) { inicio = novono; fim = novono; } else { fim->prox = novono; fim = novono; } printf(\n\nInserido com Sucesso!!!!\n); printf(\nContinuar inserindo (1-sim/2-nao)? ); scanf(%d,&continuar); }while (continuar == 1); }
II. Consultar elemento Para fazer uma consulta em uma lista dinmica necessrio saber qual elemento deseja consultar. Neste caso faremos uma consulta por matrcula. Um ponteiro auxiliar ser usado para percorrer a lista, visitando cada n a procura do elemento.
79
e-Tec Brasil
INCIO FIM
10/Ana
22/Jlia
14/Mrio
12/Vera
17/Paulo
NULL
1010
10/Ana
1040
22/Jlia
1050
14/Mrio
1070
12/Vera
1080
17/Paulo
INCIO
2
NULL
1010
FIM
22/Jlia
1040
14/Mrio
1050
12/Vera
1070
17/Paulo
1080
NULL
1040
1050
1070
1080
Na Figura 3.8 temos uma lista com trs elementos. Caso quisssemos consultar o elemento de matrcula 25, iramos percorrer a lista at chegar ao ltimo n, cujo endereo do vizinho NULL (n de endereo 1080) e ficaramos sabendo que este elemento no se encontra na lista. Quando um elemento encontrado, seus dados so apresentados e quando ele no est na lista, uma mensagem de erro deve ser dada ao usurio. O cdigo abaixo, implementado est em linguagem C, realiza um consulta de um determinado aluno: /* Consultar um aluno na lista */ void consultar() { int matc, continuar, achou=0; do{ cabec(); printf(\nConsulta aluno pelo numero de matricula\n\n); printf(\nMatricula: ); scanf(%d,&matc); noatual = inicio; while(noatual != NULL) { if (noatual->mat == matc) { achou = 1; printf(\n\nMatricula Nome\n);
e-Tec Brasil
80
Estrutura de Dados
printf(---------------------------------------\n); printf(%9d %-20s\n,noatual->mat, noatual->nome); printf(---------------------------------------\n); break; } else noatual = noatual->prox; } if (achou == 0) printf(\n\nAluno nao encontrado!!\n); printf(\nContinuar consultando (1-sim/2-nao)? ); scanf(%d,&continuar); }while (continuar == 1); }
III. Remover elemento Para remover um elemento necessrio saber qual elemento deseja remover. Para isso, a matrcula do aluno a ser removido deve ser lida. feita uma varredura em todos os ns da lista. Assim que o elemento encontrado, seus dados devem ser apresentados ao usurio (neste caso a matrcula e o nome). Dessa forma ele pode verificar se realmente aquele o elemento a ser removido. Quando o elemento no encontrado, uma mensagem de erro deve ser dada ao usurio. Nas Figuras 3.9 so ilustrados os trs casos de remoo: remover primeiro da lista, ltimo da lista, elemento no meio da lista. No (passo 1), conforme Figura 3.9a, temos a lista com cinco elementos. J no (passo 2 tambm presente na Figura 3.9a foi feita a remoo do aluno com matrcula 10. Este o primeiro n da lista. Esta remoo feita
81
e-Tec Brasil
modificando o valor do n incio para o endereo do vizinho do n que est sendo removido, neste caso, endereo 1040. Agora no (passo 3presente na Figura 3.9b foi removido a aluno de matrcula 17. Este aluno o ultimo n da lista, a sua remoo ir ter que atualizar o ponteiro fim. Alm disso, o elemento que tinha como vizinho seguinte o n de matrcula 17, ter agora NULL como vizinho. Portanto, dois ponteiros so atualizados. Ainda na Figura 3.9b o (passo 4) realiza a ltima remoo, aluno com matrcula 14 (endereo 1050), que est armazenado em um n no meio da lista. Nesta remoo, os ponteiros inicio e fim no so alterados. No entanto, o elemento que vem antes do removido (1040), ter agora como vizinho o elemento que era vizinho do que ser removido (1070).
1010 1080 1040 1080
INCIO FIM
10/Ana
22/Jlia
14/Mrio
12/Vera
17/Paulo
NULL
1010
10/Ana
1040
22/Jlia
1050
14/Mrio
1070
12/Vera
1080
17/Paulo
INCIO
2
NULL
1010
FIM
22/Jlia
1040
14/Mrio
1050
12/Vera
1070
17/Paulo
1080
NULL
1040
1050
1070
1080
INCIO
3
1040
17/Paulo 1080
NULL
FIM
1070
NULL
INCIO
4
1040
12/Vera 1070
NULL
FIM
1070
NULL
e-Tec Brasil
82
Estrutura de Dados
/* remover um aluno da lista */ void remover() { TAluno *noantrem; int matr, confrem, continuar, achou; do{ achou = 0; cabec(); printf(\nRemove aluno \n\n); printf(\nMatricula: ); scanf(%d,&matr); noatual = inicio; while(noatual != NULL) { if (noatual->mat == matr) { achou = 1; printf(\n\nMatricula Nome\n); printf(---------------------------------------\n); printf(%9d %-20s\n,noatual->mat, noatual->nome); printf(---------------------------------------\n); printf(\n\nDeseja remover o aluno (1-sim, 2-nao)? ); scanf(%d,&confrem); if (confrem ==1) { if (noatual == inicio) inicio = inicio->prox; else { noantrem->prox=noatual->prox; if (noatual == fim)
83
e-Tec Brasil
fim=noantrem; } qa--; free(noatual); printf(\n\nRemovido com sucesso!!!!\n); } else printf(\n\nRemocao cancelada\n); break; } else { noantrem = noatual; noatual = noatual->prox; } } if (achou == 0) printf(\n\nAluno nao encontrado!!\n); printf(\n\nDeseja remover outro (1-sim, 2-nao)? ); scanf(%d,&continuar); }while (continuar ==1); }
IV. Listagem de todos os elementos A operao de listagem possibilita a visualizao dos dados de todos os elementos cadastrados. feita uma pesquisa na lista partindo do endereo inicio at o ltimo n, todos os dados de todos os elementos so apresentados ao usurio.
e-Tec Brasil
84
Estrutura de Dados
O cdigo abaixo representa a impresso de todos os elementos: /* Lista todos os alunos presentes na lista */ void listar () { noatual = inicio; cabec(); printf(\nListagem de Alunos\n\n); if (qa != 0) { printf(\n\nMatricula Nome\n); printf(---------------------------------------\n); while( noatual != NULL) { printf(%9d %-20s\n,noatual->mat, noatual->nome); noatual = noatual->prox; } printf(---------------------------------------\n); printf(\n\nQuantidade de Alunos = %d\n,qa); } else printf(\n\n Nao tem nenhum aluno cadastrado); printf(\n\n\nTecle enter para voltar para o menu\n); getche(); }
A implementao do cdigo completo da lista dinmica desordenada na linguagem C estar disponibilizado junto ao AVEA em formatos . pdf e .cpp!
85
e-Tec Brasil
Vamos praticar, atravs do cdigo completo do contedo visto at o momento da aula 3 disponvel no AVEA, implemente um novo programa trocando variveis alunos, matrcula e polo por pessoa, RG e endereo. d) Lista dinmica ordenada Esta lista implementada usando ponteiros, no entanto, quando for feito o caminhamento pelos ns da lista, ela deve estar ordenada por algum campo, neste exemplo o campo de ordenao a matrcula. Esta lista possui apenas o ponteiro inicio, que guarda o endereo do primeiro elemento da lista. Operaes bsicas I. Inserir elemento Nas Figuras 3.10 (a e b) so ilustradas a insero de quatro elementos em uma lista dinmica ordenada. No (passo 1) presente na Figura 3.10a, a lista est vazia, com o ponteiro incio apontando para NULL. J no (passo 2) tambm presente na Figura 3.10a temos a insero do elemento de matrcula 17. Como a lista est vazia, o ponteiro incio vai apontar para este elemento (endereo 1080). Continuando na Figura 3.10a, no (passo 3), temos a chegada de um outro elemento, matrcula 10. verificado que ele tem a matrcula menor do que o primeiro elemento da lista, ento este novo elemento ter que ser inserido no incio da lista. Assim, o elemento novo vai apontar para o primeiro da lista e o ponteiro incio ir apontar para o novo n. Agora observaremos a Figura 3.10b, o (passo 4) ter a insero de um aluno com matrcula 14, que ser inserido no meio da lista. Para isso, teremos que descobrir entre quais elementos ele ir ser inserido, para manter a lista ordenada e fazer as ligaes dos ponteiros corretamente.
1
INCIO
NULL
INCIO
1080
17/Paulo 1080
NULL
INCIO
1010
10/Ana 1010
17/Paulo 1080
NULL
e-Tec Brasil
86
Estrutura de Dados
INCIO
1010
10/Ana 1040
14/Mrio 1050
17/Paulo 1070
NULL
INCIO
1010
10/Ana 1040
14/Mrio 1050
17/Paulo 1070
22/Jlia 1040
NULL
Finalmente, no (passo 5), conforme Figura 3.10b tivemos a insero do aluno com matrcula 22. Esse ser inserido no final da lista. O cdigo abaixo, implementado est em linguagem C, inseri um novo aluno lista: /* Funcao para inserir um novo no, ao final da lista */ void inserir () { TAluno *novono, *antinserido; int i, matl,continuar; char nomel[15]; do{ cabec(); printf(\nInserir novo aluno \n); printf(\nMatricula: ); scanf(%d,&matl); fflush(stdin); printf(\nNome: ); gets(nomel); qa++; //Aloca memoria para o novo aluno e coloca os dados novono = (TAluno *) malloc(sizeof(TAluno));
87
e-Tec Brasil
novono->mat = matl; for (i=0;i<=14;i++) novono->nome[i] =nomel[i]; antinserido = NULL; // Inserir novono na lista de alunos if (inicio == NULL) {/* Ainda nao existe nenhum aluno na lista */ inicio = novono; novono->prox = NULL; } else { noatual = inicio; if (noatual->mat > matl) {// aluno inserido no inicio da lista novono->prox = inicio; inicio = novono; } else { // aluno sera inserido no meio ou final da lista while(noatual != NULL) { if (noatual->mat < matl) {// procura o local da insercao antinserido = noatual; noatual = noatual->prox; } else // encontrou o local onde sera inserido noatual = NULL; } novono->prox = antinserido->prox; antinserido->prox = novono; }
e-Tec Brasil
88
Estrutura de Dados
} printf(\n\nInserido com Sucesso!!!!\n); printf(\nContinuar inserindo (1-sim/2-nao)? ); scanf(%d,&continuar); }while (continuar == 1); // verifica se quer continuar removendo } II. Consultar elemento Para fazer uma consulta necessrio primeiro saber qual elemento deseja consultar. Um ponteiro auxiliar ser usado para percorrer a lista, visitando cada n a procura do elemento.
INCIO
1010
10/Ana
14/Mrio
17/Paulo
22/Jlia
1040
1050
1070
1040
NULL
Na Figura 3.11 temos uma lista com quatro elementos. Caso quisssemos consultar o elemento de matrcula 25, iramos percorrer a lista at chegar ao ltimo n, cujo endereo do vizinho NULL (n de endereo 1040) e ficaramos sabendo que este elemento no se encontra na lista. Se procurssemos a matrcula 8, assim que fosse feita a comparao com o primeiro elemento da lista, j saberamos que a matricula 8 no se encontra na lista e a consulta finalizada. A busca executada enquanto no encontra o elemento procurado ou enquanto no encontra um elemento cuja matrcula maior do que a matrcula que est sendo procurada. O cdigo abaixo, implementado est em linguagem C, realiza um consulta de um determinado aluno: /* Consultar um aluno na lista */ void consultar() { int matc, continuar, achou=0; do{ cabec();
89
e-Tec Brasil
printf(\nConsulta aluno pelo numero de matricula\n\n); printf(Matricula: ); scanf(%d,&matc); noatual = inicio; // coloca ponteiro no inicio da lista while(noatual != NULL) { // percorre a lista procurando o aluno if (noatual->mat == matc) { // aluno encontrado achou = 1; printf(\n\nMat Nome \n); printf(----------------------------\n); printf(%2d %-15s\n, noatual->mat, noatual->nome); printf(----------------------------\n); break; } else {// procura no proximo aluno noatual = noatual->prox; if (noatual != NULL) { if (noatual->mat > matc) break; } } } if (achou == 0) // aluno nao esta na lista printf(\n\nAluno nao encontrado!!\n\n); printf(\nContinuar consultando (1-sim/2-nao)? ); scanf(%d,&continuar); }while (continuar == 1); }
e-Tec Brasil
90
Estrutura de Dados
III. Remover elemento A remoo em uma lista dinmica ordenada segue a mesma regra de uma lista desordenada. A nica diferena que no teremos o ponteiro fim para atualizar. Para remover um elemento necessrio saber qual elemento deseja remover. Para isso, a matrcula do aluno a ser removido deve ser lida. feita uma varredura em todos os ns da lista. Assim que o elemento encontrado, seus dados devem ser apresentados ao usurio (neste caso a matrcula e o nome). Quando o elemento no encontrado, uma mensagem de erro deve ser dada ao usurio. Na Figura 3.12 so ilustrados os dois casos de remoo: primeiro da lista e meio ou fim da lista. Quando o primeiro elemento da lista removido, (passo 2), o endereo do incio precisa ser atualizado. No (passo 3) o elemento a ser removido o ltimo da lista. Neste caso, o elemento que apontava para o elemento removido (1080), ter que apontar para o elemento que o elemento removido aponta (NULL).
INCIO
1010
10/Ana
14/Mrio
17/Paulo
22/Jlia
NULL
1040
10/Ana
2
1050
1070
17/Paulo
1040
14/Mrio
22/Jlia
NULL
INCIO
1050
1040
14/Mrio
1050
17/Paulo
1070
22/Jlia
1040
NULL
1050
1070
17/Paulo
1040
22/Jlia
14/Mrio
3
NULL
INCIO
1050
1050
14/Mrio
1070
17/Paulo
1040
NULL
1050
Fonte: FRANA S. V. A. Apostila de Estrutura de Dados
1070
O cdigo abaixo, implementado est em linguagem C, realiza uma remoo aluno: /* remover um aluno da lista */ void remover() { TAluno *noantrem; int matr, confrem, continuar, achou;
91
e-Tec Brasil
do{ achou = 0; cabec(); printf(\nRemove aluno \n\n); printf(Matricula: ); scanf(%d,&matr); noatual = inicio; //ponteiro que ira percorrer a lista while(noatual != NULL) { // percorre a lista a procura do aluno if (noatual->mat == matr) { // verifica se o aluno achou = 1; // impressao dos dados do aluno para conferencia printf(\n\nMatricula Nome\n); printf(----------------------------------------\n); printf(%9d %-15s\n, noatual->mat, noatual->nome); printf(----------------------------------------\n); printf(\n\nDeseja remover o aluno (1-sim, 2-nao)? ); scanf(%d,&confrem); if (confrem ==1) {// confirma que quer remover if (noatual == inicio) // verifica se o primeiro da lista inicio = inicio->prox; else // removido esta no meio ou final da lista noantrem->prox=noatual->prox; qa--; free(noatual); // libera memoria do no removido printf(\n\n Removido com sucesso!!!!\n); }
e-Tec Brasil
92
Estrutura de Dados
else // cancelou a remocao printf(\n\n Remocao cancelada\n); break; } else {// passa para o proximo no para continuar a busca noantrem = noatual; noatual = noatual->prox; if (noatual !=NULL) { if (noatual->mat > matr) break; } } } if (achou == 0) // o elemento nao foi encontrado na lista printf(\n\nAluno nao encontrado!!\n\n); printf(\n\nDeseja remover outro (1-sim, 2-nao)? ); scanf(%d,&continuar); }while (continuar ==1); // continuar removendo aluno }
IV. Listagem de todos os elementos A operao de listagem possibilita a visualizao dos dados de todos os elementos cadastrados. feita uma varredura na lista partindo do endereo inicio at o ltimo n, todos os dados de todos os elementos so apresentados ao usurio. O cdigo a seguir representa a impresso de todos os elementos:
93
e-Tec Brasil
/* Lista todos os alunos presentes na lista */ void listar () { noatual = inicio; // no auxiliar marca o inicio da lista cabec(); printf(\nListagem de Alunos\n\n); if (qa != 0) {// verifica se tem aluno cadastrado printf(\n\nMatricula Nome\n); printf(----------------------------------------\n); while( noatual != NULL) { // percorre toda a lista ate chegar no final printf(%9d %-15s\n, noatual->mat, noatual->nome); noatual = noatual->prox; // Faz noatual apontar para o proximo no } printf(----------------------------------------\n); printf(\n\nQuantidade de Alunos: %d\n,qa); } else printf(\n\nNao tem nenhum aluno cadastrado); printf(\n\nTecle enter para voltar para o menu...);
Assista video-aula da disciplina de Estrutura de Dados disponvel no AVEA. Aproveite para revisar os contedos da aula 3 sobre listas.
getche(); }
A implementao do cdigo completo da lista dinmica ordenada na linguagem C estar disponibilizado junto ao AVEA em formatos .pdf e .cpp Vamos praticar, atravs do cdigo completo do contedo visto at o momento da aula 3 disponvel no AVEA, implemente um novo programa trocando variveis alunos, matricula e polo por pessoa e endereo.
e-Tec Brasil
94
Estrutura de Dados
Resumo
Nesta aula abordamos uma viso geral de estrutura de dados, descrevendo de tipos primitivos e estruturados, descrevemos o tipo Lista (ordenada e desordenada) esttica e dinamicamente e implementamos suas operaes bsicas tais como: insero, remoo, consulta, listagem na linguagem C.
Atividades de aprendizagem
1. Os tipos de dados so divididos em primitivos e estruturados, comente acerca deles descrevendo-os. 2. Diferencie estruturas homogneas e heterogneas. 3. Construa um programa na linguagem C que represente uma Lista Esttica Desordenada, que possua como campos: cdigo e nome do cliente. Neste programa ser necessrio criar um menu que tenha inserir, remover, listar, consulta. Observao: Implemente um contador de registros inseridos e que o mesmo dever ser decrementado quando a informao foi excluda. 4. Construa um programa na linguagem C que represente uma Lista Dinmica Desordenada, que possua como campos: cdigo, nome do cliente. Neste programa ser necessrio criar um menu que tenha inserir, remover, listar, consulta. Observao: Implemente um contador de registros inseridos e que o mesmo dever ser decrementado quando a informao foi excluda.
95
e-Tec Brasil
Aula 4 Pilhas
Objetivos
Conhecer o funcionamento de uma Pilha. Implementar as operaes bsicas em uma estrutura pilha esttica e dinmica.
4.1. Introduo
Para entendermos o funcionamento de uma estrutura de pilha, podemos fazer uma analogia com uma pilha de pratos. Se quisermos adicionar um prato na pilha, o colocamos no topo. Para pegar um prato da pilha, retiramos o do topo. Assim, temos que retirar o prato do topo para ter acesso ao prximo prato. A estrutura de pilha funciona de maneira anloga. Cada novo elemento inserido no topo e s temos acesso ao elemento do topo da pilha. Portanto As pilhas so estruturas baseadas no princpio LIFO (last in, first out), na qual os dados que foram inseridos por ltimo na pilha sero os primeiros a serem removidos. Existem trs operaes bsicas que devem ser implementadas numa estrutura de pilha: operao para empilhar um novo elemento, inserindo-o no topo, operao para desempilhar um elemento, removendo-o do topo e a operao para consultar qual elemento est no topo da pilha. comum nos referirmos a essas operaes pelos termos em ingls push (empilhar) e pop (desempilhar).
Aula 4 Pilhas
97
e-Tec Brasil
Vetor Vazio
1
10/ Cincias
2
7/ Ingls
3
4/ Fsica
O cdigo abaixo, implementado est em linguagem C, inseri um novo aluno pilha: /* Funcao para inserir um novo livro na pilha */ void inserir () { int continuar; do{ cabec(); printf(\nColocar livro no topo da pilha \n); printf(\nCodigo do livro: ); scanf(%d,&ll.codigo); printf(\nTitulo do Livro: ); fflush(stdin); gets(ll.titulo); // Inserir livro na pilha if (tampilha <30) { /* Se ainda tem vaga na pilha */ livro[tampilha] = ll; tampilha++;
e-Tec Brasil
98
Estrutura de Dados
printf(\n\nInserido com Sucesso!!!!\n\n); } else /* Pilha cheia*/ printf(\n\nPilha cheia, Livro nao inserido!!!!\n\n); printf(\n Continuar inserindo (1-sim/2-nao)? ); scanf(%d,&continuar); }while (continuar == 1); // verifica se quer continuar inserindo livros } II. Consultar topo da pilha Em uma pilha, a consulta feita apenas do elemento do topo, ou seja, o ltimo elemento a ser inserido. Assim, teremos a informao de qual ser o prximo elemento a ser retirado. Na Figura 4.2, o elemento do topo da pilha o livro de cdigo 4 e ttulo Fsica, armazenado na posio 3 do vetor. Quando o vetor estiver vazio, apresentada uma mensagem de pilha vazia ao usurio.
Pilha com trs elementos
10/ Cincias 7/ Ingls 4/ Fsica
O cdigo abaixo, implementado est em linguagem C, realiza um consulta de um determinado aluno: /* Consultar topo da pilha*/ void consultatopo() { cabec(); printf(\nConsulta topo da pilha\n); if (tampilha != 0) { printf(\n\nCod Titulo \n); printf(----------------------------------------------------\n); printf(%2d %-20s \n, livro[tampilha-1].codigo, livro[tampilha-1].titulo);
Aula 4 Pilhas
99
e-Tec Brasil
printf(-----------------------------------------------------\n); } else printf(\n\nA pilha esta vazia!!\n\n); printf(\n\nTecle enter para voltar para o menu\n); getche(); } III. Remover topo da pilha Em uma pilha, o elemento removido sempre o que chegou h menos tempo, ou seja, o elemento da ltima posio do vetor. Na Figura 4.3 iremos remover o elemento do topo da pilha, neste caso, o elemento da posio 3. No h necessidade de deslocamentos.
Pilha com trs elementos
10/ Cincias 7/ Ingls 4/ Fsica
1
10/ Cincias
2
7/ Ingls
O cdigo abaixo, implementado est em linguagem C, realiza uma remoo aluno: /* remover um livro da pilha */ void retirapilha() { int i, confrem, continuar; do{ cabec(); printf(\nRetira livro do topo da pilha \n); if (tampilha != 0) {// verifica se tem elementos na pilha printf(\n\nCodigo Titulo Editora\n); printf(---------------------------------------------------\n);
e-Tec Brasil
100
Estrutura de Dados
printf(%6d %-20s \n, livro[tampilha-1].codigo, livro[tampilha-1].titulo); printf(---------------------------------------------------\n); printf(\n\nconfirma retirada do livro (1-sim, 2-nao)? ); scanf(%d,&confrem); if (confrem ==1) { // confirma que quer remover tampilha--; printf(\n\n Retirado da Pilha com sucesso!!!!\n\n); } else // cancelou a remocao printf(\n\n Retirada cancelada\n\n); } else // pilha vazia printf(\n\nPilha vazia!!\n\n); printf(\n\nDeseja retirar outro livro(1-sim, 2-nao)? ); scanf(%d,&continuar); }while (continuar ==1); // continuar retirando livro da pilha } IV. Listagem de todos os elementos da pilha A operao de listagem possibilita a visualizao dos dados de todos os elementos da pilha. feita uma varredura no vetor e todos os dados de todos os elementos so apresentados ao usurio. O cdigo abaixo representa a impresso de todos os elementos: /* Lista todos os livros da pilha */ void listar () { int i; cabec();
Aula 4 Pilhas
101
e-Tec Brasil
printf(\nListagem dos livros da pilha\n); if (tampilha != 0) { printf(\n\nCodigo Titulo Editora\n); printf(-----------------------------------------------------\n); for (i=tampilha-1;i>=0;i--) printf(%6d %-20s \n, livro[i].codigo, livro[i].titulo); printf(-----------------------------------------------------\n); printf(\n\nQuantidade de livros na pilha = %d\n,tampilha); } else printf(\n\n Nao tem nenhum livro na pilha); printf(\n\n\nTecle enter para voltar para o menu\n); getche(); } A implementao do cdigo completo da pilha esttica na linguagem C estar disponibilizado junto ao AVEA em formatos .pdf e .cpp!
e-Tec Brasil
102
Estrutura de Dados
INICIO
NULL
INICIO
1080
17/Ingls
1080
NULL
INICIO
1010
25/Fsica
1010
17/Ingls
1080
NULL
INICIO
1030
10/Lgica
1030
25/Fsica
1010
17/Ingls
1080
NULL
Cada elemento que chega, ser inserido no incio da estrutura. Portando, o ponteiro inicio sempre modificado a cada insero. Na Figura 4.4 a pilha inicia vazia, com o ponteiro incio apontando para NULL (passo 1). No (passo 2) um elemento inserido na pilha, por ser o primeiro, ele no tem vizinho e o ponteiro incio passa a apontar para o novo n (endereo 1080). No (passo 3) um novo elemento inserido, o ponteiro incio deve ser atualizado e o novo n deve apontar para o elemento que estava no incio da pilha (endereo 1080). No (passo 4), um novo elemento inserido e as atualizaes dos ponteiros devem ser feitas. O cdigo abaixo, implementado est em linguagem C, inseri um novo aluno pilha: /* Funcao para inserir um novo no, no inicio da pilha */ void inserir () { TLivro *novono; int i, codl, continuar; char titl[30]; do{
Aula 4 Pilhas
103
e-Tec Brasil
cabec(); printf(\nColocar livro no topo da pilha \n); printf(\nCodigo do livro: ); scanf(%d,&codl); printf(\nTitulo do Livro: ); fflush(stdin); gets(titl); // Inserir livro na pilha tampilha++; //Aloca memoria para o novo livro novono = (TLivro *) malloc(sizeof(TLivro)); novono->codigo = codl; for (i=0;i<=29;i++) novono->titulo[i] =titl[i]; novono->prox = inicio; inicio = novono; printf(\n\nInserido com Sucesso!!!!\n\n); printf(\nContinuar inserindo (1-sim/2-nao)? ); scanf(%d,&continuar); }while (continuar == 1); // verifica se quer continuar inserindo livros } II. Consultar topo da pilha Em uma pilha, a consulta feita apenas do elemento do topo, ou seja, o ltimo elemento a ser inserido, que neste caso o elemento apontado pelo ponteiro inicio. Se o ponteiro incio aponta para NULL significa que a pilha est vazia. O cdigo a seguir, implementado est em linguagem C, realiza um consulta de um determinado aluno:
e-Tec Brasil
104
Estrutura de Dados
/* Consultar livro do topo da pilha */ void consultatopo() { cabec(); printf(\nConsulta topo da pilha\n\n); if (inicio != NULL) { printf(\n\nCodigo Titulo \n); printf(-----------------------------------------------------\n); printf(%6d %-20s \n, inicio->codigo, inicio->titulo); printf(-----------------------------------------------------\n); } else printf(\nA pilha est vazia!!\n\n); printf(\n\nTecle enter para voltar para o menu\n); getche(); } III. Remover topo da pilha Em uma pilha, o elemento removido sempre o que chegou h menos tempo, ou seja, o elemento apontado pelo ponteiro inicio. Na Figura 4.5 iremos remover o elemento do topo da pilha. O ponteiro incio deve ser atualizado, apontando para o elemento que era vizinho do elemento removido.
INICIO NULL
1030
10/Lgica
1030
25/Fsica
1010
17/Ingls
1080
25/Fsica
1010
17/Ingls
1080
NULL
25/Fsica
1010 Figura 4.5: Remoo da pilha dinmica
Fonte: FRANA S. V. A. Apostila de Estrutura de Dados
17/Ingls
1080
NULL
Aula 4 Pilhas
105
e-Tec Brasil
O cdigo abaixo, implementado est em linguagem C, realiza uma remoo aluno: /* remover livro do topo da pilha */ void retirapilha() { int confrem, continuar; do{ cabec(); printf(\nRetira livro do topo da pilha \n); noatual = inicio; //ponteiro que ira apontar para o primeiro no if (inicio != NULL) { // verifica se tem elementos na pilha printf(\n\nCodigo Titulo \n); printf(---------------------------------------------------\n); printf(%6d %-20s \n, inicio->codigo, inicio->titulo); printf(---------------------------------------------------\n); printf(\n\nconfirma retirada do livro (1-sim, 2-nao)? ); scanf(%d,&confrem); if (confrem ==1) { // confirma que quer remover inicio = inicio->prox; free(noatual); // libera memoria do no removido tampilha--; printf(\n\n Retirado da Pilha com sucesso!!!!\n\n); } else // cancelou a remocao printf(\n\n Retirada cancelada\n\n); } else // pilha vazia
e-Tec Brasil
106
Estrutura de Dados
printf(\n\nPilha vazia!!\n\n); printf(\n\nDeseja retirar outro livro(1-sim, 2-nao)? ); scanf(%d,&continuar); }while (continuar ==1); // continuar retirando livro da pilha } IV. Listagem de todos os elementos da pilha A operao de listagem possibilita a visualizao dos dados de todos os elementos da pilha. feita uma varredura na pilha e todos os dados de todos os elementos so apresentados ao usurio. O cdigo abaixo representa a impresso de todos os elementos: /* Lista todos os livros da pilha */ void listar () { noatual = inicio; // no auxiliar marca o inicio da lista cabec(); printf(\nListagem dos livros da pilha\n\n); if (inicio != NULL) { printf(\n\nCodigo Titulo \n); printf(----------------------------------------------------\n); while( noatual != NULL) { // percorre toda a pilha printf(%6d %-20s \n, noatual->codigo, noatual->titulo); noatual = noatual->prox; // Faz noatual apontar para proximo no } printf(-----------------------------------------------------\n); printf(\n\nQuantidade de livros na pilha = %d\n,tampilha); } else
Aula 4 Pilhas
107
e-Tec Brasil
printf(\n\n Nao tem nenhum livro na pilha); printf(\n\n\nTecle enter para voltar para o menu\n); getche(); } A implementao do cdigo completo da pilha dinmica na linguagem C estar disponibilizado junto ao AVEA em formatos .pdf e .cpp!
Resumo
Assista video-aula da disciplina de Estrutura de Dados disponvel no AVEA. Aproveite para revisar os contedos da aula 3 sobre listas.
Nesta aula descrevemos o tipo pilha esttica e dinamicamente e implementamos suas operaes bsicas tais como: insero, remoo, consulta, listagem na linguagem C.
Atividades de aprendizagem
1. Qual o critrio de insero e remoo utilizada pela Pilha? 2. A Figura 4.6 representa uma pilha implementada atravs de um vetor de 10 posies. Observe que so realizadas as operaes de remoo e insero na Pilha. Qual seria a nova configurao da Pilha aps as seguintes operaes: Remoo; Remoo; Remoo; Insero do elemento A; Insero do elemento B; Remoo; Insero do elemento WW;
Topo da Pilha: [4]
X Y W Z
10
e-Tec Brasil
108
Estrutura de Dados
a) Quantos elementos aps as remoes e inseres possui o vetor? b) Quantas posies aps as remoes e inseres possui o vetor? c) Faa o desenho da nova Pilha. 3. Implemente uma Pilha Esttica em linguagem C que armazene como dados, 10 (dez) nomes de Pessoas. Implemente as operaes de insero, remoo e consulta. Observao: colocar o cdigo complemento
4. Implemente o cdigo da questo anterior para Pilha Dinmica. Observao: colocar o cdigo complemento
Aula 4 Pilhas
109
e-Tec Brasil
111
e-Tec Brasil
colocando as restries adequadas nas operaes de adicionar e remover elementos de uma lista, parece com o que foi feito com as pilhas, s que agora os elementos so adicionados e removidos de extremidades diferentes. A pilha segue o critrio LIFO (Last In First Out), j a fila segue o critrio FIFO (First In, First Out).
e-Tec Brasil
112
Estrutura de Dados
memria grande demais ou insuficiente para uma determinada aplicao. J as filas dinmicas so bastante vantajosas quando no se conhece o tamanho mximo da fila. Dessa forma, medida que desejamos inserir novos elementos na fila, basta alocar um espao de memria adequado e inserir este novo elemento. Porm, como em listas encadeadas, a principal desvantagem da implementao dinmica est no fato de que um elemento da fila sempre conter uma referncia para o outro elemento da fila, o que gera uma utilizao maior de memria.
As operaes bsicas que podem ser implementadas em uma fila so: I. criar uma fila vazia; II. inserir elemento no final da fila; III. remover o elemento do incio da fila; IV. consultar o primeiro da fila; V. listar todos os elementos da fila. Para um melhor entendimento do que seja uma fila, temos abaixo uma implementao de uma SIMULAO de fila de matrculas no curso tcnico de informtica.
113
e-Tec Brasil
b) Inserir elemento Todo elemento que vai ser inserido em uma fila colocado no final da estrutura. Os alunos vo sendo inseridos por ordem de chegada. No exemplo da Figura 5.3 so inseridos 3 alunos na fila.
Fila com 3 alunos
Maria 1212 Pedro 4844 Jos 5611
Logo abaixo, temos a funo inserir ( ) implementada na linguagem C para inserir um novo aluno no final da fila. void inserir () { int continuar; do { printf(\n Chegada de novo aluno na fila \n); printf(\n Numero da Matricula: );
e-Tec Brasil
114
Estrutura de Dados
Aluno[tamfila] = Al; tamfila++; } else /* Fila cheia*/ printf(\n\nFila cheia, Aluno nao inserido!!!!\n\n); printf(\n\nAluno Inserido com Sucesso!!!!\n\n);
scanf(%d,&continuar); } c) Consultar primeiro da fila Em uma fila, a consulta feita apenas do primeiro elemento da fila. Assim, teremos a informao de qual ser o prximo elemento a ser retirado. Na Figura 5.4, o primeiro elemento da fila a aluna Maria, com matrcula 1212.
Fila com 3 alunos
Maria 1212 Pedro 4844 Jos 5611
Logo abaixo, temos a funo consultarprimeiro( ) implementada na linguagem C para consultar o primeiro aluno da fila.
115
e-Tec Brasil
void consultarprimeiro ( ) { cabec(); printf(\nConsulta primeiro aluno da fila\n); if (tamfila != 0) { printf(\nMatricula Nome Polo\n);
getche(); }
d) Remover primeiro da fila Observando a Figura 5.5, em uma fila, o elemento removido sempre o que chegou h mais tempo, ou seja, o elemento da primeira posio do vetor. Na figura abaixo iremos remover o primeiro elemento da fila (neste caso, Maria-1212). Os elementos seguintes devem ser deslocados uma posio a frente. Com isso, o segundo elemento da fila passa a ser o primeiro, o terceiro passa a ser o segundo e assim por diante.
Fila com 3 elementos
Maria 1212 Pedro 4844 Jos 5611
Retirada do primeiro da la
Maria 1212 Pedro 4844 Jos 5611
e-Tec Brasil
116
Estrutura de Dados
Logo abaixo, temos a funo retirafila ( ) implementada na linguagem C para remover o aluno da fila. void retirafila ( ) { int i, confrem, continuar;
for (i=0; i<tamfila; i++) Aluno[i] = Aluno[i+1]; tamfila--; printf(\n\n Aluno retirado da fila com
sucesso!!!!\n\n); } else printf(\n\n Retirada cancelada\n\n); } else printf(\n\nFila vazia!!\n\n); printf(\n\nDeseja retirar outro aluno(1-sim, 2-nao)? );
scanf(%d,&continuar); }
Aula 5 Filas e rvores
117
e-Tec Brasil
e) Listagem de todos os elementos da fila A operao de listagem possibilita a visualizao dos dados de todos os elementos da fila. feita uma varredura no vetor e todos os dados de todos os elementos so apresentados. Logo abaixo, temos a funo listar ( ) implementada na linguagem C para remover o aluno da fila. void listar () { int i; cabec ( ); printf(\nListagem de alunos da fila\n); if (tamfila != 0) { printf(\nMatricula Nome Polo\n);
printf(--------------------------------------------\n); for (i=0;i<tamfila;i++) printf(%4d %-15s %2d\n, Aluno[i].Matricula, Aluno[i].Nome, Aluno[i].Polo); printf(--------------------------------------------------\n); } else } printf(\n\n Nao tem nenhum aluno na fila); printf(\n\nQuantidade de alunos na fila = %d\n,tamfila);
e-Tec Brasil
118
Estrutura de Dados
A implementao do cdigo completo da fila esttica na linguagem C estar disponibilizado junto ao AVEA em formatos .pdf e .cpp! Depois de vermos como funcionam as operaes bsicas em uma fila esttica (vetor) e sua implementao na linguagem C, vamos entender o que uma FILA DINMICA e v sua implementao, na prxima seo.
INICIO 1 2
FINAL 3 NULL
A Fila dinmica sempre implementada com 2 ponteiros, o 1 (primeiro) no incio da fila e o 2 (segundo) no final. As operaes bsicas que so implementadas em uma fila esttica so as mesmas na fila dinmica. A implementao abaixo tambm SIMULA fila de matrculas no curso tcnico de informtica. I. Inserir elemento Todo elemento que vai ser inserido em uma fila colocado no final da estrutura.
119
e-Tec Brasil
INCIO FIM
NULL NULL
INCIO FIM
1010 1010
12/Maria 1010
NULL
INCIO FIM
1010 1070
12/Maria 1010
12/Maria 1070
NULL
A Figura 5.7 ilustra a chegada de dois alunos na fila. Inicialmente a fila est vazia, portanto o valor do ponteiro incio e fim NULL (passo 1). Quando um elemento vai ser inserido, a memria alocada e os dados so armazenados (passo 2). Todo n criado em uma fila dinmica, no tem vizinho seguinte, por isso ele aponta para NULL. Na insero do primeiro elemento, os ponteiros incio e fim apontam para este elemento (no exemplo, endereo de memria 1010). No passo 3 temos a chegada da aluna Ana-10, que ser armazenado no final da estrutura, o ltimo elemento da fila o ter (endereo de memria 1070) como vizinho e o ponteiro fim ir apontar para o novo elemento. Logo abaixo, temos a funo inserir ( ) implementada na linguagem C para inserir um novo aluno no final da fila dinmica, agora utilizando ponteiros.
void inserir () { TAluno *novono; int i, Matriculal, Polol, continuar; char Nomel[15];
do{ printf(\n Chegada de novo aluno na fila \n); printf(\n Numero da Matricula: );
e-Tec Brasil
120
Estrutura de Dados
for (i=0;i<=14;i++) novono->Nome[i] =Nomel[i]; novono->Polo = Polol; novono->prox = NULL; // Inserir novo Aluno na fila de Alunos
if (inicio == NULL) {
inicio = novono; fim = novono; } else { fim->prox = novono; fim = novono; } printf(\n\nAluno Inserido com Sucesso!!!!\n\n); printf(\n Continuar inserindo (1-sim/2-nao)? );
121
e-Tec Brasil
II. Consultar primeiro da fila Em uma fila, a consulta feita apenas do primeiro elemento da fila. Assim teremos a informao de qual ser o prximo elemento a ser retirado. O primeiro elemento da fila o elemento do endereo incio. Quando incio estiver apontando para NULL, significa que a fila est vazia. Logo abaixo, temos a funo consultarprimeiro ( ) implementada na linguagem C para consultar o primeiro aluno da fila dinmica.
void consultarprimeiro ( ) { printf(\nConsulta primeiro aluno da fila\n\n); noatual = inicio; // coloca ponteiro no inicio da lista if (noatual != NULL) { printf(\n\n Matricula Nome Polo\n);
getche(); }
III. Remover primeiro da fila Na Figura 5.8, em uma fila, o elemento removido sempre o que chegou h mais tempo, ou seja, o elemento apontado por incio. Quando um elemento removido, o endereo do ponteiro incio deve apontar para o vizinho do primeiro da fila.
e-Tec Brasil
122
Estrutura de Dados
INCIO 1010
1
12/Maria 10/Ana 1040 24/Jos 1050 28/Joana 1070 37/Lia 1080
NULL
FIM
1080
1010
INCIO 1040
2
12/Maria 1010
10/Ana 1040
24/Jos 1050
28/Joana 1070
37/Lia 1080
NULL
FIM
1080
10/Ana 1040
24/Jos 1050
28/Joana 1070
37/Lia 1080
NULL
Logo abaixo, temos a funo retirafila ( ) implementada na linguagem C para retirar o primeiro aluno da fila dinmica.
do{ printf(\nRetira primeiro Aluno da fila \n\n); noatual = inicio; if (noatual != NULL) {
scanf(%d,&confrem);
123
e-Tec Brasil
if (confrem ==1) {
inicio = inicio->prox; free(noatual); tamfila--; n\n); } else printf(\n\n Retirada cancelada\n\n); } else // fila vazia printf(\n\n Retirado da fila com sucesso!!!!\
scanf(%d,&continuar); fila }
IV. Listagem de todos os elementos da fila A operao de listagem possibilita a visualizao dos dados de todos os elementos da fila. feita uma varredura na fila e todos os dados de todos os elementos so apresentados. Logo abaixo, temos a funo listar( ) implementada na linguagem C para mostrar todos os alunos matriculados, ou seja, inseridos na fila dinmica.
e-Tec Brasil
124
Estrutura de Dados
noatual->Nome, noatual->Polo); noatual = noatual->prox; } printf(---------------------------------------------------\n); } else printf(\n\n Nao tem nenhum aluno na fila);
Assista video-aula Estrutura de Dados - Aula 05 - Parte I disponvel em http://etapi. cefetpi.br/Videos/Estrutura_ de_dados_5_parte1/index. html. Aproveite para revisar os contudos da aula sobre filas e rvores.
getche(); }
A implementao do cdigo completo da fila dinmica na linguagem C estar disponibilizado junto a plataforma AVEA em formatos .pdf e .cpp!
125
e-Tec Brasil
Outros exemplos de estruturas em forma de rvores so: A diviso de um livro em captulos, sees, tpicos. A rvore genealgica de uma pessoa. A organizao dos diretrios (pastas) do Sistema Operacional Windows Vista.
e-Tec Brasil
126
Estrutura de Dados
Formalmente, uma rvore um conjunto finito T de um ou mais ns, tais que: a) existe um n denominado raiz da rvore. b) os demais ns formam m 0 conjuntos disjuntos S1, S2, ..., Sm onde cada um destes conjuntos uma rvore. As rvores Si (1 i n) recebem a denominao de subrvores. Uma rvore nunca poder ter mais de uma raiz. Em computao, rvores (e especialmente rvores binrias) so usadas para armazenar dados (chaves e outros campos de informao) em seus ns da mesma forma que listas ligadas e vetores. E assim como as demais estruturas de dados, as rvores tambm possuem sua representao grfica. As trs formas mais comuns de representao grfica de uma rvore so demonstradas a seguir: 1. Representao por parnteses aninhados ( A (B) ( C (D (G) (H)) (E) (F (I)) ) ) 2. Diagrama de incluso
A B C D G E H F I
127
e-Tec Brasil
3. Representao hierrquica
A B D C E F
e-Tec Brasil
128
Estrutura de Dados
1 2 3
Se, por exemplo, n1 for a raiz de uma rvore binria e n2 for a raiz da sua sub-rvore direita ou esquerda, ento diz-se que n1 o pai de n2, e que n2 o filho direito ou esquerdo de n1. O n n2 um descendente de n1 e n1 o seu ascendente. Um n que no tenha filhos uma folha. Dois ns so irmos se so os filhos direito e esquerdo do mesmo pai. Nvel de um n numa rvore binria: a raiz da rvore tem nvel 1. O nvel de outro n qualquer uma unidade mais que o nvel do pai. Uma rvore binria completa de nvel n uma rvore em que cada n de nvel n uma folha e em que todos os ns de nvel menor que n tm sub-rvores direita e esquerda no vazias. Exemplificando melhor, temos a rvore da Figura 5.13 a seguir.
Podemos concluir que: Essa rvore possui 9 ns distribudos aleatoriamente. O n A a raiz da rvore, que tem 2 sub-rvores com B e C, como razes. O nmero de sub-rvores de um n determina o grau desse n. Dessa forma, A e C tem grau 2 e B tem grau 1. O ns que tem grau zero so denominados terminais ou folhas, nesse caso o n F.
129
e-Tec Brasil
Utilizando a relao de hierarquia existente na rvore binria, podemos conhecer os antepassados de um n, basta identificarmos todos os ns ao longo do caminho entre a raiz e este n. Ex: os antepassados de G so, na ordem: os ns A-B-D. Outro conceito importante no estudo de rvores e o conceito de nvel, que representa a distncia do nodo at a raiz. Por definio, a raiz da rvore tem nvel 1. Os ns B e C tm nvel 2, os ns D, E e F tm nvel 3, e assim por diante. O n de maior nvel nos fornece a altura (ou profundidade) da rvore. Sendo assim, a rvore acima apresenta altura 4. Podemos tambm calcular o nmero mximo de ns possveis em uma rvore binria, pode-se utilizar o valor da altura h e a frmula 2h 1, como est exemplificado na Figura 5.14 a seguir.
Para uma melhor exemplificao de rvores binrias pode ser utilizar a representao de expresses aritmticas, de tal forma que a hierarquia (prioridade) dos operadores fique clara (bem definida). A representao feita de tal forma que a prioridade das operaes fique implcita: o operador de menor prioridade da expresso aritmtica aparece na raiz da rvore; a subexpresso que forma o operando da esquerda deste operador d origem subrvore da esquerda da raiz; enquanto que a subexpresso que forma o operando que forma o operando da direita d origem subrvore da direita da raiz. Os operandos so sempre representados nos ns terminais, conforme exemplificada na Figura 5.15. Suponhamos as seguintes expresses aritmticas: (3 + 6) * (4 - 1) + 5
e-Tec Brasil
130
Estrutura de Dados
5 + 3 6 _
131
e-Tec Brasil
Em geral so utilizadas trs formas de caminhamentos em rvores binrias e estas so determinadas dependendo da ordem em que so visitados o n raiz, sua subrvore esquerda e sua subrvore direita, o termo visitar significa a realizao de alguma operao sobre a informao do n, como modificao da mesma, impresso ou qualquer outra. No caso de rvores binrias, existem determinadas ordens de caminhamento mais frequentemente utilizadas. As trs ordens principais so: a) Caminhamento pr-fixado (raiz-esquerda-direita): 1. visita a raiz; 2. percorre a subrvore da esquerda; 3. percorre a subrvore da direita. b) Caminhamento in-fixado (esquerda-raiz-direita): 1. percorre a subrvore da esquerda; 2. visita a raiz; 3. percorre a subrvore da direita. c) Caminhamento ps-fixado (esquerda-direita-raiz): 1. percorre a subrvore da esquerda; 2. percorre a subrvore da direita; 3. visita a raiz. O termo visita est sendo usado para indicar o acesso a um n para fins executar alguma operao sobre ele.
e-Tec Brasil
132
Estrutura de Dados
As trs ordens de caminhamento acima apresentadas, aplicadas sobre a rvore da Figura 5.16, produzem as seguintes sequncias: pr-fixado: A B G C D E F; in-fixado: G B C E F D A; ps-fixado: G F E D C B A.
Assista video-aula Estrutura de Dados - Aula 05 - Parte II disponvel em http://etapi. cefetpi.br/Videos/Estrutura_ de_dados_5_parte2/index. html. Aproveite para revisar os contedos da aula sobre filas e rvores..
133
e-Tec Brasil
135
e-Tec Brasil
Na verdade, ordenao de dados o processo pelo qual determinada a ordem na qual devem se apresentar as entradas de uma tabela de modo que obedeam sequncia citada por um ou mais de seus campos. Estes campos especificados como determinantes da ordem so chamados chaves de ordenao. Portanto, vamos discutir ordenao de vetores. Como veremos, os algoritmos de ordenao podem ser aplicados a qualquer informao, desde que exista uma ordem definida entre os elementos. Podemos, por exemplo, ordenar um vetor de valores inteiros, adotando uma ordem crescente ou decrescente. Podemos tambm aplicar algoritmos de ordenao em vetores que guardam informaes mais complexas, por exemplo um vetor que guarda os dados relativos a alunos de uma turma, com nome, nmero de matrcula, etc. Nesse caso, a ordem entre os elementos tem que ser definida usando uma das informaes do aluno como chave da ordenao: alunos ordenados pelo nome, alunos ordenados pelo nmero de matrcula, etc. Nos casos em que a informao complexa, raramente se encontra toda a informao relevante sobre os elementos do vetor no prprio vetor; em vez disso, cada componente do vetor pode conter apenas um ponteiro para a informao propriamente dita, que pode ficar em outra posio na memria. Assim, a ordenao pode ser feita sem necessidade de mover grandes quantidades de informao, para re-arrumar as componentes do vetor na sua ordem correta. Para trocar a ordem entre dois elementos, apenas os ponteiros so trocados. Em muitos casos, devido ao grande volume, a informao pode ficar em um arquivo de disco, e o elemento do vetor ser apenas uma referncia para a posio da informao nesse arquivo. Na prxima seo, ser descrito a analisado o mtodo de ordenao por troca, conhecido como Bolha ou BubbleSort. Por troca, entende-se os mtodos baseados na troca de posio dos dados, de forma a orden-los. Estes mtodos caracterizam-se por efetuarem a ordenao sucessiva de pares de elementos, trocando-os de posio caso estejam fora da ordem desejada.
e-Tec Brasil
136
Estrutura de Dados
O algoritmo de Ordenao Bolha, ou Bubblesort, recebeu este nome pela imagem pitoresca usada para descrev-lo: os elementos maiores so mais leves, e sobem como bolhas at suas posies corretas. A ideia fundamental fazer uma srie de comparaes entre os elementos do vetor. Quando dois elementos esto fora de ordem, h uma inverso e esses dois elementos so trocados de posio, ficando em ordem correta. Assim, o primeiro elemento comparado com o segundo. Se uma inverso for encontrada, a troca feita. Em seguida, independente se houve ou no troca aps a primeira comparao, o segundo elemento comparado com o terceiro, e, caso uma inverso seja encontrada, a troca feita. O processo continua at que o penltimo elemento seja comparado com o ltimo. Com este processo, garante-se que o elemento de maior valor do vetor ser levado para a ltima posio. A ordenao continua, posicionando o segundo maior elemento, o terceiro, etc., at que todo o vetor esteja ordenado. A Figura 6.1 mostra o que acontece com o vetor no decorrer da execuo do mtodo da bolha.
Valores originais do vetor 8 6 10 2 16 4 20 14 12 12 12 12 12 12 12 12 20 18 18 18 18 18 18 18 18 18 18 18 20 20
Como A[0] maior que A[1], eles trocam os valores 8 2 4 6 20 14 10 16 Como A[2] maior que A[3], eles trocam os valores 2 4 8 6 10 16 20 14 Como A[3] maior que A[4], eles trocam os valores 4 6 8 2 16 20 14 10 6 6 6 6 6 6 6 8 8 8 8 8 8 8 2 2 2 2 2 2 2 10 10 10 10 10 10 10 16 4 4 4 4 4 4 4 16 16 16 16 16 16 20 20 20 14 14 14 14 14 14 14 20 12 12 12
137
e-Tec Brasil
Iniciaremos comparando os dois primeiros elementos (o primeiro com o segundo). Como eles esto desordenados, ento, trocamos as suas posies (8 e 6). Comparamos agora o segundo com o terceiro (8 e 10). Como eles esto desordenados, ento, trocamos as suas posies, e assim sucessivamente. Chegamos agora ao final do vetor! Note que aps essa primeira fase de comparaes e trocas o maior elemento, 20, est na sua posio correta e final. Na prxima fase, todo o processo ser repetido, porm com a diferena que agora as comparaes e trocas no sero mais feitas at o final do vetor, mais sim at o ltimo nmero que antecede aquele que chegou a sua posio correta no nosso caso o penltimo elemento. Vamos mais uma vez iniciar o processo, comparando os dois primeiros elementos do vetor. Verificamos que quando os valores esto ordenados, no ser necessria a troca de posies. Note que as comparaes e trocas dessa fase chegaram ao final, uma vez que o ltimo elemento j est em sua posio correta e que levamos o segundo maior elemento para a sua posio correta. Faz-se isso at que o vetor esteja totalmente ordenado. Uma funo que implementa esse algoritmo na linguagem C apresentada a seguir. A funo recebe como parmetros o nmero de elementos e o ponteiro do primeiro elemento do vetor que se deseja ordenar. Vamos considerar a ordenao de um vetor de valores inteiros. /* Algoritmo de Ordenao Bolha */ void bolha (int n, int* v) { int i, j; for (i=n-1; i>=1; i--) { for (j=0; j<i; j++) { if (v[j] > v[j+1]) { /* troca */
v[j+1] = temp; }
Embora o algoritmo de ordenao da Bolha ou BubbleSort seja simples, este pode ser altamente ineficiente e raramente usado do ponto de vista computacional.
} } }
e-Tec Brasil
138
Estrutura de Dados
Abaixo a funo principal para testar esse algoritmo, lembrando que a funo getch ( ) responsvel por ficar aguardando que uma tecla seja pressionada para que o programa continue sua execuo normal. /* Funo Principal */ /* Testa Algoritmo de Ordenao Bolha */ int main (void) { int i; int v[8] = { 25, 48, 37, 12, 57, 86, 33, 92}; printf(Vetor Desordenado: \n); for (i=0; i<8; i++)
Ordenado\n\n); getch(); bolha(8,v); printf(Vetor Ordenado: \n); for (i=0; i<8; i++)
getch(); } Para evitar que o processo continue mesmo depois de o vetor estar ordenado, podemos interromper o processo quando houver uma passagem inteira sem trocas, usando uma variante do algoritmo apresentado acima: return 0;
139
e-Tec Brasil
/* Ordenao Bolha 2 Verso */ void bolha2 (int n, int* v) { int i, j; for (i=n-1; i>0; i--) { int troca = 0; for (j=0; j<i; j++) if (v[j]>v[j+1]) { /* troca */
int temp = v[j]; v[j] = v[j+1]; v[j+1] = temp; troca = 1; } if (troca == 0) /* nao houve troca */
return; } } Implemente um cdigo em C, que utilize um vetor de 20 elementos inteiros, gerado com valores lidos pelo teclado. E ordene esse algoritmo utilizando o mtodo da Bolha. Poste no AVEA da disciplina o arquivo de sua atividade. Esse mesmo algoritmo pode ser aplicado a vetores que guardam outras informaes. O cdigo escrito acima pode ser reaproveitado, a menos de alguns detalhes. Primeiro, a assinatura da funo deve ser alterada, pois deixamos de ter um vetor de inteiros; segundo, a forma de comparao entre os elementos tambm deve ser alterada Para aumentar o potencial de reuso do nosso cdigo, podemos reescrever o algoritmo de ordenao apresentado acima tornando-o independente da informao armazenada no vetor. A implementao do cdigo completo em linguagem C que demonstra o mtodo de ordenao bolha numa lista desordenada e esttica de alunos relacionados pela matrcula, nome, notas e mdia. estar disponibilizado no AVEA em formatos .pdf e .cpp!
e-Tec Brasil
140
Estrutura de Dados
141
e-Tec Brasil
elemento. Portanto, a forma mais simples de fazermos uma pesquisa num vetor consiste em percorrermos o vetor, elemento a elemento, verificando se o elemento de interesse igual a um dos elementos do vetor. Esse algoritmo pode ser implementado conforme ilustrado pelo cdigo a seguir, considerando-se um vetor de nmeros inteiros. A funo apresentada tem como valor de retorno o ndice do vetor no qual foi encontrado o elemento; se o elemento no for encontrado, o valor de retorno 1. int pesquisa (int n, int* vet, int elem) { int i; for (i=0; i<n; i++) { if (elem == vet[i]) return i; /* elemento encontrado */
/* percorreu todo o vetor e no encontrou elemento */ } Esse algoritmo de pesquisa extremamente simples, mas pode ser muito ineficiente quando o nmero de elementos no vetor for muito grande. Isto porque o algoritmo (a funo, no caso) pode ter que percorrer todos os elementos do vetor para verificar que um determinado elemento est ou no presente. Dizemos que no pior caso ser necessrio realizar n comparaes, onde n representa o nmero de elementos no vetor. Portanto, o desempenho computacional desse algoritmo varia linearmente com relao ao tamanho do problema. Abaixo temos a funo principal para testar esse algoritmo de pesquisa linear. Lembrando que a funo getch( ) responsvel por ficar aguardando que uma tecla seja pressionada para que o programa continue sua execuo normal. #include <stdio.h> #include <conio.h> /* Programa que faz a pesquisa em um vetor */ int main (void) { return -1;
e-Tec Brasil
142
Estrutura de Dados
int v[8] = {24,11,47, 38,58,77,66,82}; int e = 58; /* informao que se deseja pesquisar */ int p; p = pesquisa(8,v,e); if (p == -1) printf(Elemento nao encontrado.\n);
else }
Em diversas aplicaes reais, precisamos de algoritmos de pesquisa mais eficientes. Seria possvel melhorarmos a eficincia do algoritmo de pesquisa mostrado acima? Infelizmente, se os elementos estiverem armazenados em uma ordem aleatria no vetor, no temos como melhorar o algoritmo de pesquisa, pois precisamos verificar todos os elementos. No entanto, se assumirmos, por exemplo, que os elementos esto armazenados em ordem crescente, podemos concluir que um elemento no est presente no vetor se acharmos um elemento maior, pois se o elemento que estamos pesquisando estivesse presente ele precederia um elemento maior na ordem do vetor. O cdigo abaixo ilustra a implementao da pesquisa linear assumindo que os elementos do vetor esto ordenados (vamos assumir ordem crescente). int pesquisa_ord (int n, int* vet, int elem) { int i; for (i=0; i<n; i++) { if (elem == vet[i]) return i; /* elemento encontrado */
else
143
e-Tec Brasil
} }
e-Tec Brasil
144
Estrutura de Dados
O cdigo a seguir ilustra uma implementao de pesquisa binria num vetor de valores inteiros ordenados de forma crescente. int pesquisa_bin (int n, int* vet, int elem) { /* no inicio consideramos todo o vetor */ int ini = 0; int fim = n-1; int meio; /* enquanto a parte restante for maior que zero */ while (ini <= fim) { meio = (ini + fim) / 2; if (elem < vet[meio]) fim = meio 1; /* ajusta posico final */
else
else } }
O desempenho desse algoritmo muito superior ao de pesquisa linear. Novamente, o pior caso caracteriza-se pela situao do elemento que estamos procurando no estar no vetor. Quantas vezes precisamos repetir o procedimento de subdiviso para concluirmos que o elemento no est presente no vetor? A cada repetio, a parte considerada na pesquisa dividida metade.
145
e-Tec Brasil
O algoritmo de pesquisa binria consiste em repetirmos o mesmo procedimento recursivamente, podendo ser naturalmente implementado de forma recursiva. Embora a implementao no recursiva seja mais eficiente e mais adequada para esse algoritmo, a implementao recursiva mais sucinta e vale a pena ser apresentada. Na implementao recursiva, temos dois casos a serem tratados. No primeiro, a pesquisa deve continuar na primeira metade do vetor, logo chamamos a funo recursivamente passando como parmetros o nmero de elementos dessa primeira parte restante e o mesmo ponteiro para o primeiro elemento, pois a primeira parte tem o mesmo primeiro elemento do que o vetor como um todo. No segundo caso, a pesquisa deve continuar apenas na segunda parte do vetor, logo passamos na chamada recursiva, alm do nmero de elementos restantes, um ponteiro para o primeiro elemento dessa segunda parte. Para simplificar, a funo de pesquisa apenas informa se o elemento pertence ou no ao vetor, tendo como valor de retorno falso (0) ou verdadeiro (1). Uma possvel implementao usando essa estratgia mostrada a seguir. int pesquisa_bin_rec (int n, int* vet, int elem) { /* testa condio de contorno: parte com tamanho zero */ if (n <= 0)
return 0; else { /* deve pesquisar o elemento entre os ndices 0 e n - 1 */ int meio = (n - 1) / 2; if (elem < vet[meio])
146
Estrutura de Dados
Em particular, devemos notar a expresso &vet[meio+1] que, como sabemos, resulta num ponteiro para o primeiro elemento da segunda parte do vetor. Se quisermos que a funo tenha como valor de retorno o ndice do elemento, devemos acertar o valor retornado pela chamada recursiva na segunda parte do vetor. Os mesmos algoritmos de pesquisa sequencial e binria podem ser aplicados a vetores que guardam outras informaes, alm de nmeros inteiros. A implementao do cdigo completo em linguagem C, onde o cdigo representa um sistema de cadastro de alunos num curso tcnico de informtica, onde so armazenadas as informaes referente matrcula, nome, situao (aprovado ou reprovado) de cada aluno, e ainda duas notas e a partir dessas notas gerado uma mdia. O cdigo para aplicar a pesquisa sequencial e binria estar disponibilizado no AVEA em formatos .pdf e .cpp!
Resumo
Nesta aula abordamos conceitos de classificao ou ordenao de dados. O mtodo de ordenao adotado foi o mtodo de ordenao por troca, conhecido como Bolha ou BubbleSort. Por se tratar de um mtodo muito simples de implementar, recebeu este nome pela imagem pitoresca usada para descrev-lo: os elementos maiores so mais leves, e sobem como bolhas at suas posies corretas. E foi feita a implementao do BubbleSort na linguagem C. Aps ordenarmos os elementos de um determinado conjunto, necessrio se faz saber realizar uma pesquisa. Foram ento, disponibilizadas informaes sobre estratgias de pesquisa conhecidas como: Pesquisa Sequencial e Binria. E suas posteriores implementaes na linguagem C.
Assista video-aula da disciplina de Estrutura de Dados Aula 06 Parte II disponvel em http://cefetpi.nucleoead.net/ etapi/. Aproveite para revisar os contedos da aula sobre ordenao e pesquisa.
Atividades de aprendizagem
1. Demonstre graficamente a ordenao dos dados 25, 48, 37, 12, 57, 86, 33, 92 usando o mtodo da Bolha. 2. Implemente um cdigo em C, que utilize um vetor de 2000 elementos inteiros, gerado com valores lidos pelo teclado. E ordene esse algoritmo utilizando o mtodo da Bolha. 3. Em diversas aplicaes reais, precisamos de algoritmos de busca mais eficientes. Seria possvel melhorarmos a eficincia do algoritmo de busca?
147
e-Tec Brasil
Referncias
ASCENCIO, A. F. G., CAMPOS, E. A. V. Fundamentos da Programao de Computadores. Editora Pearson Prentice Hall. 2 edio, 2007. FRANA S. V. A. Apostila de Estrutura de Dados. Acessado em 04/12/2011 http:// www.4shared.com/office/MWxzbSi9/Estrutura_de_Dados_-_Sonia_Vir.html. HOROWITZ, E.; SAHNI, S. Fundamentos de Estruturas de Dados. Rio de Janeiro, Ed. Campus, 1986. LEISERSON, C., RIVEST, L. Algoritmos - Teoria e Pratica. Ed.Campus, 1 edio, 2002. MIZRAHI, Victorine Viviane. Treinamento em C. Ed Pearson Prentice Hall, 2 edio, 2008. PINTO, Wilson Silva. Introduo ao Desenvolvimento de Algoritmos e Estrutura de dados. Ed. rica LTDA. TENEMBAUM, Aaron M. Estrutura de Dados Usando C. So Paulo: Makron Books do Brasil, 1995. TREMBLAY, Jean Paul e RICHARD, B. Bunt. Cincias dos Computadores, Uma Abordagem Algortmica. Ed. McGraw Hill. SCHILDT, H. C Completo e Total, Ed. Makron Books, 3 edio, 1997. SZWARCFITER, J Luiz; MARKENZON, Lilian. Estruturas de Dados e seus Algoritmos. Rio de Janeiro: Livros Tcnicos e Cientficos Editora S. A, 2 edio, 1994. VELLOSO, Paulo. Estruturas de Dados. Rio de Janeiro: Ed. Campus, 1991. VILLAS, Marcos V & Outros. Estruturas de Dados: Conceitos e Tcnicas de implementao. Rio de Janeiro: Ed. Campus, 1993. WIRTH, N. Algoritmos e Estruturas de Dados. Rio de Janeiro, Prentice-Hall. 1989.
e-Tec Brasil
148
Referncias
149
e-Tec Brasil