1. Capítulo 9
ESTRUTURAS DE DADOS HOMOGÊNEAS
Vimos, no início deste curso, ser possível dar um nome para uma posição de memória,
sendo que a esta será associado um valor qualquer. Pois bem, acontece que, muitas vezes, esta
forma de definição, ou melhor, de alocação de memória, não é suficiente para resolver certos
problemas computacionais. Imagine por exemplo, como faríamos para construir um algoritmo,
para ler o nome de N pessoas e que imprimisse um relatório destes mesmos nomes, mas
ordenados alfabeticamente? Não seria uma tarefa simples, haja visto não ser possível determinar
quantos nomes seriam lidos. Mesmo que soubéssemos o número de pessoas, digamos 1.000
pessoas, teríamos que definir 1.000 variáveis do tipo caractere, como é mostrado abaixo:
algoritmo “loucura”
var
Nome1,Nome2,Nome3,...., Nome999, Nome1000 : caractere
inicio
<sequencia de comandos>
fimalgoritmo
Considere o tamanho do algoritmo, e o trabalho braçal necessário para construi-lo. Isto só
com 1.000 nomes. Imagine agora 1.000.000 de pessoas. A construção deste algoritmo começaria a
ficar inviável na prática. Para resolver problemas como este e outros, foi criado um novo conceito
para alocação de memória sendo, desta forma, também criado uma nova maneira de definir
variáveis, a qual foi denominada de variável indexada.
Uma variável indexada corresponde a uma sequência de posições de memória, a qual
daremos um único nome, sendo que cada uma destas pode ser acessada através do que
conhecemos por índice. O índice corresponde a um valor numérico (exceto REAL), ou a um valor
caractere (exceto STRING). Cada uma das posições de memória de uma variável indexada pode
receber valores no decorrer do algoritmo como se fosse uma variável comum, a única diferença
reside na sintaxe de utilização desta variável.
As estruturas de dados homogêneas permitem agrupar diversas informações dentro de
uma mesma variável. Este agrupamento ocorrerá obedecendo sempre ao mesmo tipo de dado, e
é por esta razão que estas estruturas são chamadas homogêneas.
A utilização deste tipo de estrutura de dados recebe diversos nomes, como: variáveis
indexadas, variáveis compostas, variáveis subscritas, arranjos, vetores, matrizes, tabelas em
memória ou arrays. Os nomes mais usados e que utilizaremos para estruturas homogêneas são:
matrizes (genérico) e vetores (matriz de uma linha e várias colunas).
Exemplos:
2. Cada elemento dos arrays podem ser referenciados através de índices. Exemplos:
V[1] = 4 M[1,1] = 3
V[2] = 7 M[2,3] = 4
V[5] = 3 M[3,1] = 2
1. MATRIZES DE UMA DIMENSÃO OU VETORES
Este tipo de estrutura em particular é também denominado por profissionais da área como
matrizes unidimensionais. Sua utilização mais comum está vinculada à criação de tabelas.
Caracteriza-se por ser definida uma única variável vinculada dimensionada com um determinado
tamanho. A dimensão de um vetor é constituída por constantes inteiras e positivas. Os nomes
dados às matrizes seguem as mesmas regras de nomes utilizados para indicar as variáveis simples.
A sintaxe do comando de definição de vetores é a seguinte:
var
<nome_da_variável> : vetor [<indice_inicial>..<indice_final>] de <tipo_de_dado>
Exemplo:
var V : vetor [1..10] de inteiro
1.1. OPERAÇÕES BÁSICAS COM VETORES
Do mesmo modo que acontece com variáveis simples, também é possível operar com
variáveis indexadas. Contudo não é possível operar diretamente com o conjunto completo, mas
com cada um de seus componentes isoladamente.
O acesso individual a cada componente de um vetor é realizado pela especificação de sua
posição no mesmo por meio do seu índice. No exemplo anterior foi definida uma variável V capaz
de armazenar 10 número inteiros. Para acessar um elemento deste vetor deve-se fornecer o nome
do mesmo e o índice do componente desejado do vetor (um número de 1 a 10, neste caso).
Por exemplo, V[1] indica o primeiro elemento do vetor, V[2] indica o segundo elemento do
vetor e V[10] indica o último elemento do vetor.
3. Portanto, não é possível operar diretamente sobre vetores como um todo, mas apenas
sobre seus componentes, um por vez. Por exemplo, para somar dois vetores é necessário somar
cada um de seus componentes dois a dois. Da mesma forma as operações de atribuição, leitura e
escrita de vetores devem ser feitas elemento a elemento.
1.1.1. Atribuição de Uma Matriz do Tipo Vetor
No capítulo sobre as instruções primitivas, o comando de atribuição foi definido como:
<nome_da_variável> := <expressão>
No caso de vetores (variáveis indexadas), além do nome da variável deve-se
necessariamente fornecer também o índice do componente do vetor onde será armazenado o
resultado da avaliação da expressão.
Exemplo:
V[1] := 15
V[2] := 150
V[5] := 10
V[10] := 35
1.1.2. Leitura de Dados de Uma Matriz do Tipo Vetor
A leitura de um vetor é feita passo a passo, um de seus componentes por vez, usando a
mesma sintaxe da instrução primitiva da entrada de dados, onde além do nome da variável, deve
ser explicitada a posição do componente lido:
LEIA <nome_da_variável> [<índice>]
Uma observação importante a ser feita é a utilização de uma estrutura de repetição (Para;
Enquanto) a fim de efetuar a operação de leitura repetidas vezes, em cada uma delas lendo um
determinado componente do vetor. De fato esta construção é muito comum quando se opera
com vetores, devido à necessidade de se realizar uma mesma operação com os diversos
componentes dos mesmos. Na verdade, são raras as situações que se deseja operar isoladamente
com um único componente do vetor.
O algoritmo a seguir exemplifica a operação de leitura de um vetor:
algoritmo “exemplo_leitura_de_vetor”
var
numeros : vetor [1..10] de inteiro
i : inteiro
inicio
para i de 1 ate 10 faca
leia (numeros[i])
fimpara
fimalgoritmo
4. O algoritmo acima ilustra a operação de leitura de um vetor usando a estrutura de
repetição Para. Podemos realizar a mesma operação usando a estrutura de repetição Enquanto.
algoritmo “exemplo_leitura_de_vetor_2”
var
numeros : vetor [1..10] de inteiro
i : inteiro
inicio
i := 1
enquanto i <= 10 faca
leia (numeros[i])
i := i + 1
fimenquanto
fimalgoritmo
1.1.3. Escrita de Dados de Uma Matriz do Tipo Vetor
A escrita de um vetor obedece à mesma sintaxe da instrução primitiva de saída de dados e
também vale lembrar que, além do nome do vetor, deve-se também especificar por meio do
índice o componente a ser escrito.
ESCREVA <nome_da_variável> [ <índice> ]
O algoritmo a seguir exemplifica a operação de leitura e escrita de um vetor, utilizando a
construção Para:
algoritmo “exemplo_escrita_de_vetor”
var
numeros : vetor [1..10] de inteiro
i : inteiro
inicio
para i de 1 ate 10 faca
leia (numeros[i])
fimpara
para i de 1 ate 10 faca
escreva (numeros[i])
fimpara
fimalgoritmo
Um exemplo mais interessante é mostrado a seguir, onde um vetor de dez números é lido
e guardado no vetor numeros. Paralelamente, a soma destes números é calculada e mantida na
variável soma, que posteriormente é escrita.
5. algoritmo “exemplo_escrita_de_vetor_com_soma”
var
numeros : vetor [1..10] de inteiro
i : inteiro
soma : inteiro
inicio
soma := 0
para i de 1 ate 10 faca
leia (numeros[i])
soma := soma + numeros[i]
fimpara
para i de 1 ate 10 faca
escreva (numeros[i])
fimpara
escreva (“Soma = ”, soma)
fimalgoritmo
1.2. EXEMPLOS DE APLICAÇÃO DE VETORES
O espectro de aplicação de vetores em algoritmos é muito extenso, mas normalmente os
vetores são usados em duas tarefas muito importantes no processamento de dados: pesquisa e
classificação.
A pesquisa consiste na verificação da existência de um valor dentro de um vetor. Trocando
em miúdos, pesquisar um vetor consiste em procurar dentre seus componentes um determinado
valor.
A classificação de um vetor consiste em arranjar seus componentes numa determinada
ordem, segundo um critério específico. Por exemplo, este critério pode ser a ordem alfabética de
um vetor de dados caractere, ou então a ordem crescente ou decrescente para um vetor de dados
numéricos. Há vários métodos de classificação, mas o mais conhecido é o método da bolha de
classificação (Bubble Sort).
1.2.1. O Método da Bolha de Classificação
Este método não é o mais eficiente, mas é um dos mais populares devido à sua
simplicidade.
A filosofia básica deste método consiste em “varrer” o vetor, comparando os elementos
vizinhos entre si. Caso estejam fora de ordem, os mesmos trocam de posição entre si. Procede-se
assim até o final do vetor. Na primeira “varredura” verifica-se que o último elemento do vetor já
está no seu devido lugar (no caso de ordenação crescente, ele é o maior de todos). A segunda
“varredura” é análoga à primeira e vai até o penúltimo elemento. Este processo é repetido até que
seja feito um número de varreduras igual ao número de elementos a serem ordenados menos um.
Ao final do processo o vetor está classificado segundo o critério escolhido.
6. O exemplo a seguir ilustra o algoritmo bubble sort para ordenar 50 número inteiros em
ordem crescente:
algoritmo "Bubble Sort"
var
i, j : inteiro
aux : inteiro
numeros : vetor[1..10] de inteiro
inicio
para i de 1 ate 10 faca
leia(numeros[i])
fimpara
para i de 1 ate 10 faca
para j de 1 ate 9 faca
se numeros[j] > numeros[j+1] entao
aux <- numeros[j]
numeros[j] <- numeros[j+1]
numeros[j+1] <- aux
fimse
fimpara
fimpara
para i de 1 ate 10 faca
escreval(i, " - ", numeros[i])
fimpara
fimalgoritmo
Podemos observar também que para ordenar o vetor em ordem decrescente basta
inverter o sinal de comparação no teste da condição lógica:
Se numeros[j] > numeros[j+1] para Se numeros[j] < numeros[j+1]
2. MATRIZES COM MAIS DE UMA DIMENSÃO
Este tipo de estrutura também tem sua principal utilização vinculada à criação de tabelas.
Caracteriza-se por ser definida uma única variável vinculada dimensionada com um determinado
tamanho. A dimensão de uma matriz é constituída por constantes inteiras e positivas. Os nomes
dados às matrizes seguem as mesmas regras de nomes utilizados para indicar as variáveis simples.
A sintaxe do comando de definição de matrizes de duas dimensões é a seguinte:
var
<nome_da_variável> : vetor [<linha_inicial>..<linha_final> ,
<coluna_inicial>..<coluna_final>] de <tipo_de_dado>
7. Exemplo:
var M : vetor [1..5,1..10] de inteiro
Também é possível definir matrizes com várias dimensões, por exemplo:
var
N : vetor [1..4] de inteiro
O : vetor [1..50,1..4] de inteiro
P : vetor [1..5,1..50,1..4] de inteiro
Q : vetor [1..3,1..5,1..50,1..4] de inteiro
R : vetor [1..2,1..3,1..5,1..50,1..4] de inteiro
A utilidade de matrizes desta forma é muito grande. No exemplo acima, cada matriz pode
ser utilizada para armazenar uma quantidade maior de informações:
a matriz N pode ser utilizada para armazenar 4 notas de um aluno
a matriz O pode ser utilizada para armazenar 4 notas de 50 alunos
a matriz P pode ser utilizada para armazenar 4 notas de 50 alunos de 5 disciplinas
a matriz Q pode ser utilizada para armazenar 4 notas de 50 alunos de 5 disciplinas, de 3
turmas
a matriz R pode ser utilizada para armazenar 4 notas de 50 alunos de 5 disciplinas, de 3
turmas, de 2 colégios
2.1. OPERAÇÕES BÁSICAS COM MATRIZES DE DUAS DIMENSÕES
Do mesmo modo que acontece com os vetores, não é possível operar diretamente com o
conjunto completo, mas com cada um de seus componentes isoladamente.
O acesso individual a cada componente de uma matriz é realizado pela especificação de
sua posição na mesma por meio do seu índice. No exemplo anterior foi definida uma variável M
capaz de armazenar 10 número inteiros em cada uma das 5 linhas. Para acessar um elemento
desta matriz deve-se fornecer o nome da mesma e o índice da linha e da coluna do componente
desejado da matriz (um número de 1 a 5 para a linha e um número de 1 a 10 para a coluna, neste
caso).
Por exemplo, M[1,1] indica o primeiro elemento da primeira linha da matriz, M[1,2] indica
o segundo elemento da primeira linha da matriz, M[1,10] indica o último elemento da primeira
linha da matriz e M[5,10] indica o último elemento da última linha da matriz.
Da mesma forma como vetores, não é possível operar diretamente sobre matrizes como
um todo, mas apenas sobre seus componentes, um por vez. Por exemplo, para somar duas
matrizes é necessário somar cada um de seus componentes dois a dois.
Da mesma forma, as operações de atribuição, leitura e escrita de matrizes devem ser feitas
elemento a elemento.
8. 2.1.1. Atribuição de Uma Matriz de Duas Dimensões
Na atribuição de matrizes, da mesma forma que nos vetores, além do nome da variável
deve-se necessariamente fornecer também o índice do componente da matriz onde será
armazenado o resultado da avaliação da expressão. O índice referente ao elemento é composto
por tantas informações quanto o número de dimensões da matriz. No caso de ter duas dimensões,
o primeiro número se refere à linha e o segundo número se refere à coluna da matriz em que se
encontra a informação.
Exemplo:
M[1,1] := 15
M[1,10] := 10
M[3,5] := 20
M[5,10] := 35
2.1.2. Leitura de Dados de Uma Matriz de Duas Dimensões
A leitura de uma matriz é feita passo a passo, um de seus componentes por vez, usando a
mesma sintaxe da instrução primitiva da entrada de dados, onde além do nome da variável, deve
ser explicitada a posição do componente lido:
LEIA <nome_da_variável> [<linha>,<coluna>]
Uma observação importante a ser feita é a utilização de estruturas de repetição aninhadas
ou encadeadas a fim de efetuar a operação de leitura repetidas vezes, em cada uma delas lendo
um determinado componente da matriz. Esta construção é muito comum quando se opera com
matrizes, devido à necessidade de se realizar uma mesma operação com os diversos componentes
das mesmas.
O algoritmo a seguir exemplifica a operação de leitura de uma matriz:
algoritmo “exemplo_leitura_de_matriz”
var
mat : vetor [1..5,1..10] de inteiro
lin, col : inteiro
inicio
para lin de 1 ate 5 faca
Para col de 1 ate 10 faca
leia (mat[lin,col])
fimpara
fimpara
fimalgoritmo
O algoritmo acima ilustra a operação de leitura de uma matriz usando a estrutura de
repetição Para. Podemos realizar a mesma operação usando a estrutura de repetição Enquanto.
9. algoritmo “exemplo_leitura_de_matriz_2”
var
mat : vetor [1..5,1..10] de inteiro
lin, col : inteiro
inicio
lin := 1
col := 1
enquanto lin <= 5 faca
enquanto col <= 10 faca
leia (mat[lin,col])
col := col+1
fimenquanto
col := 1
lin := lin+1
fimenquanto
fimalgoritmo
2.1.3. Escrita de Dados de Uma Matriz de Duas Dimensões
A escrita de uma matriz obedece à mesma sintaxe da instrução primitiva de saída de dados
e também vale lembrar que, da mesma forma que com vetores, além do nome da matriz, deve-se
também especificar por meio do índice o componente a ser escrito:
ESCREVA <nome_da_variável> [<linha>,<coluna>]
O algoritmo a seguir exemplifica a operação de leitura e escrita de uma matriz, utilizando
as construções Para aninhadas ou encadeadas:
algoritmo “exemplo_escrita_de_matriz”
var
mat : vetor [1..5,1..10] de inteiro
lin, col : inteiro
inicio
para lin de 1 ate 5 faca
para col de 1 ate 10 faca
leia (mat[lin,col])
fimpara
fimpara
para lin de 1 ate 5 faca
para col de 1 ate 10 faca
escreva (mat[lin,col])
fimpara
fimpara
fimalgoritmo
10. Um exemplo mais interessante é mostrado a seguir, onde uma matriz de 5 linhas por 10
colunas é lida e guardada na matriz numeros. A seguir é efetuada e escrita a soma dos elementos
da 2ª linha e também a soma dos elementos da 3ª coluna.
algoritmo “exemplo_escrita_de_matriz_com_soma”
var
mat : matriz[1..5,1..10] de inteiro
lin, col : inteiro
somal2, somac3 : inteiro
inicio
para lin de 1 ate 5 faca
para col de 1 ate 10 faca
leia (mat[lin,col])
fimpara
fimpara
para lin de 1 ate 5 faca
para col de 1 ate 10 faca
escreva (mat[lin,col])
fimpara
fimpara
somal2 := 0
somac3 := 0
para col de 1 ate 10 faca
somal2 := somal2 + mat[2,col]
fimpara
para lin de 1 ate 5 faca
somac3 := somac3 + mat[lin,3]
fimpara
escreva (“Soma Linha 2 = ”, somal2)
escreva (“Soma Coluna 3 = ”, somac3)
fimalgoritmo
EXERCÍCIOS PROPOSTOS
Questão 01:
Quais são os valores impressos pelo algoritmo abaixo?
algoritmo “1”
var
a : inteiro
x : real
v : vetor [1..5] de real
inicio
v[1] := 2
v[2] := 4
11. v[3] := 1
v[4] := 5
v[5] := 3
x := v[1]+v[5]
escreva (x)
x := v[2]-v[5]
escreva (x)
x := v[4]*v[1]-x
escreva (x)
a := 3
x := v[a]
escreva (x)
x := v[a]/v[v[a]]
escreva (x)
fimalgoritmo
Questão 02:
Mostre qual é a configuração do vetor depois de executado o algoritmo abaixo.
I A M O S R O G L A
1 2 3 4 5 6 7 8 9 10
algoritmo “2”
var
x : inteiro
palavra : vetor [1..10] de caractere
aux : caractere
inicio
para x de 1 ate 5 faca
aux := palavra[5+x]
palavra[5+x] := palavra[x]
palavra[x] := aux
fimpara
para x de 1 ate 2 faca
aux := palavra[x]
palavra[x] := palavra[6-x]
palavra[6-x] := aux
fimpara
palavra[7] := “T”
fimalgoritmo
Questão 03:
Calcule o número de elementos de cada um dos vetores abaixo:
a) vet *-5..5+
b) nome *0..10+
c) oc *1..10+
12. d) arr *0..n+
e) conta*1..50+
Questão 04:
Dado um vetor VET, inteiro de 100 posições, fazer um algoritmo para cada um dos itens abaixo:
a) preenche-lo com o valor inteiro 30.
b) preenche-lo com os números inteiros 1, 2, 3, 4, … 100
c) preencher VET*i+ com 1, se i é ímpar e com 0 se i for par
Questão 05:
Fazer um algoritmo para ler as notas de 40 alunos de uma turma, calcular e mostrar a média das
notas e o número de alunos que tiraram nota acima da média.
Questão 06:
Construir um algoritmo que leia dois vetores (A e B) de 50 elementos cada um e crie um 3º vetor
acumulando a soma dos elementos desses dois vetores, sempre utilizando o mesmo índice.
Mostre os valores do 3º vetor somente.
Obs.: Leia os valores dos vetores primeiramente para depois imprimir o vetor C resultante.
Questão 07:
Escrever um algoritmo que construa um vetor A de 10 elementos reais. Após isso, construa e
imprima um outro vetor B formado da seguinte maneira:
a) os elementos de índice par têm o valor de A dividido por 2
b) os elementos de índice ímpar têm o valor de A multiplicado por 3
Questão 08:
Fazer um algoritmo para ler 20 números e mostrá-los na ordem inversa de leitura, ou seja, o último
número lido deve ser o primeiro a ser apresentado.
Questão 09:
Fazer um algoritmo para ler 50 números. Ordenar os números em ordem crescente. Mostrar os
números sequencialmente depois de ordenados.
Questão 10:
Fazer um algoritmo para ler 50 números. Ordenar os números em ordem decrescente. Mostrar os
números sequencialmente depois de ordenados.
13. Questão 11:
Dada a matriz MAT abaixo:
ANTES DEPOIS
1 2 3 4 1 2 3 4
1 O Q * I 1
2 E * E S 2
3 R E U S 3
4 A * * S 4
Qual será a configuração de MAT depois de executado o algoritmo abaixo?
algoritmo “11”
var
mat : vetor [1..4,1..4] de caractere
lin, col : inteiro
aux : caractere
inicio
para lin de 1 ate 3 faca
para col de lin+1 ate 4 faca
aux := mat[lin,col]
mat[lin,col] := mat[col,lin]
mat[col,lin] := aux
fimpara
fimpara
aux := mat[1,1]
mat[1,1] := mat[4,4]
mat[4,4] := aux
aux := mat[2,2]
mat[2,2] := mat[3,3]
mat[3,3] := aux
fimalgoritmo
Questão 12:
Escreva algoritmos independentes para a criação e inicialização das seguintes matrizes:
a)
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
15 17 18 19 20
21 22 23 24 25
14. b)
18 20 22 24
10 12 14 16
2 4 6 8
c)
P S
P S
S P
S P
Questão 13:
Elabore um algoritmo para ler as cinco notas de cada um dos 50 alunos de uma sala. O total de
linhas corresponde a quantidade de alunos. Calcule e mostre a média de cada aluno. Calcule e no
final informe a média geral da turma.
Questão 14:
Fazer um algoritmo que:
a) Leia uma matriz A, de dimensão 5 x 3. Cada linha da matriz é fornecida como entrada.
b) Determine a matriz transposta de A.
c) Mostre a matriz transposta.
Questão 15:
Fazer um algoritmo que:
a) Leia uma matriz A, de dimensão 3 x 3. Cada linha da matriz é fornecida como entrada.
b) Some todos os elementos da matriz.
c) Encontre quais elementos da matriz são pares.
d) Multiplique os elementos da coluna 3.
e) Mostre os elementos da diagonal principal.
Questão 16:
Fazer um algoritmo que:
a) Leia uma matriz A, de dimensão 4 x 4. Cada linha da matriz é fornecida como entrada.
b) Verifique se os valores da diagonal secundária são primos.
15. Questão 17:
Preencha uma matriz 5x5 de números inteiros e escreva os números cuja soma da linha e coluna
resultem num número ímpar.
Questão 18:
Preencha uma matriz 5x5 de números inteiros e escreva os dados contidos em uma coluna
fornecida.
Questão 19:
Dado uma matriz de ordem NxN faça um algoritmo que verifique se a matriz é simétrica (aij=aji).
Questão 20:
Dado uma matriz NxM de valores reais faça um algoritmo que faça a leitura destes valores e ao
final da leitura de todos, imprimir o seguintes relatório:
a) Qual a soma dos valores de cada coluna da matriz;
b) Listar os valores que são menores que a média dos valores;
c) Qual a soma dos elementos da diagonal secundária;
Questão 21:
Dado uma matriz NxM de valores inteiros escreva um algoritmo que faça a leitura destes valores e
ao final coloque os elementos ordenados primeiro pela linha e depois pela coluna.