Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados...

28
Estruturas de Dados Aula 5: Matrizes 14/04/2014

Transcript of Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados...

Page 1: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Estruturas de DadosAula 5: Matrizes

14/04/2014

Page 2: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Matrizes

• Conjuntos bidimensionais declarados estaticamentefloat mat[4][3]; acesso de elemento: mat[2][0]linearizado=unidimensional:

float mat[3*4]; acesso de elemento: mat[2*3+0]

• Declaração de um vetor (estática ou dinâmica?)int v[10]int *v;v = (int*) malloc (n*sizeof(int));v = (int*) realloc (v, m*sizeof(int));

Page 3: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Vetor – declaração estática

• int v[10]• Precisamos saber o tamanho do vetor antes da

execução do programa• v armazena o endereço de memória ocupado

pelo primeiro elemento do vetor*v e v[0]*(v+1) e v[1]

• Escopo de declaração local– Se o vetor for declarado dentro da função, não

pode ser acessado fora da função

Page 4: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Vetor – declaração dinâmica

• int *v;• v = (int*) malloc (n*sizeof(int));• Tamanho do vetor pode ser definido em tempo

de execução do programa• Variável ponteiro aponta para a primeira

posição do vetor• Área ocupada pelo vetor permanece fora das

funções até que seja liberada explicitamente por free()

Page 5: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Matrizes

float mat[4][3] = {{5.0,10.0,15.0},{20.0,25.0,30.0},{35.0,40.0,45.0},

{50.0,55.0,60.0}};Iteracaõ típica sobre todos os elementos:i=0;i<lin;i++

j=0;j<col;j++

Page 6: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Vetores bidimensionais (matrizes)

• Elementos acessados pela indexação m[i][j]i acessa linha e j coluna

• Elemento inicial m[0][0]• “m” representa um ponteiro para o primeiro

“vetor-linha”, composto por 3 elementos.• Pode ser inicializada na declaração:

– float mat [4][3] = {1,2,3,4,5,6,7,8,9,10,11,12};

– float mat [][3] = {1,2,3,4,5,6,7,8,9,10,11,12};

Page 7: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Passagem para funções

• Tipo passado para função é o “vetor linha”– void f (..., float (*mat)[3], ...);

– void f (..., float mat [][3], ...);

Page 8: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Matrizes Dinâmicas

• Conjuntos bidimensionais não podem ser alocados dinamicamente no C

• Abstrações conceituais com vetores são necessárias para alocarmos matrizes dinamicamente

Page 9: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Matrizes representadas por vetor simples

• Matriz é representada por um vetor unidimensional– Primeiras posições do vetor armazenam os

elementos da primeira linha– As posições seguintes armazenam da segunda

linha, e assim por diante

• Conceitualmente, estamos trabalhando com uma matriz

• Concretamente, estamos representando um vetor unidimensional

• Exige disciplina para acessar os elementos

Page 10: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Matrizes representadas por vetor simples

• mat [i][j]V[k], com k = i*n+j, onde n é o número de

colunas da matriz

Page 11: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Matriz representada por vetor simples

• mat [i][j] mapeado para v[i*n + j]

• m e n são as dimensões da matriz (de tamanho m*n elementos)

float *mat;...mat = (float*) malloc (m*n*sizeof(float));...

Page 12: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Operações com Matrizes

• Exemplo: função transposta– Dada uma matriz, cria dinamicamente a matriz

transposta

• Matriz de entrada: mat (m x n)• Matriz de saída: trp

• Uma matriz Q é a matriz transposta de M, se Qij = Mji

float* transposta (int m, int n, float* mat);

Page 13: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Exemplo – matriz com vetor simples

float* transposta (int m, int n, float* mat);{ int i, j; float* trp; trp = (float*) malloc (n*m*sizeof (float)); for (i=0; i<m; i++)

for (j=0; j<n; j++) trp[j*m+i] = mat [i*n+j];

return trp;}

Page 14: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Matriz representada por vetor de ponteiros

• Cada linha da matriz é representada por um vetor separado

• A matriz é representada por um vetor de vetores– Vetor de ponteiros– Cada elemento do vetor armazena o endereço

de memória do primeiro elemento de cada linha

Page 15: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Matriz representada por vetor de ponteiros

Page 16: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Matriz representada por vetor de ponteiros

• Precisamos alocar memória para o vetor de ponteiros e atribuir os endereços das linhas da matriz

int i;float **mat; /*vetor de ponteiros*/...mat = (float**)malloc (m*sizeof(float*));for (i=0; i<m; i++)

mat[i] = (float*) malloc (n*sizeof(float));

Page 17: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Matriz representada por vetor de ponteiros

• Para liberar o espaço de memória alocado...for (i=0; i<m; i++)

free (mat[i]);

free (mat);

Page 18: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Operações com Matrizes

• Exemplo: função transposta– Dada uma matriz, cria dinamicamente a matriz

transposta

• Matriz de entrada: mat (m x n)• Matriz de saída: trp

• Uma matriz Q é a matriz transposta de M, se Qij = Mji

float* transposta (int m, int n, float* mat);float** transposta (int m, int n, float** mat);

Page 19: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Exemplo – matriz com vetor simples

float* transposta (int m, int n, float* mat);{ int i, j; float* trp; trp = (float*) malloc (n*m*sizeof (float)); for (i=0; i<m; i++)

for (j=0; j<n; j++) trp[j*m+i] = mat [i*n+j];

return trp;}

Page 20: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Exemplo – matriz com vetor de ponteiros

float** transposta (int m, int n, float** mat);{ int i, j; float** trp; trp = (float**) malloc (n*sizeof (float*));

for (i=0; i<n; i++)trp[i] = (float*) malloc(m*sizeof(float));

for (i=0; i<m; i++) for (j=0; j<n; j++)

trp[j][i] = mat [i][j]; return trp;}

Page 21: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Resumindo

• Matriz representada por vetor bidimensional estático:– elementos acessados com indexação dupla m[i]

[j]

• Matriz representada por um vetor simples:– conjunto bidimensional representado em vetor

unidimensional

• Matriz representada por um vetor de ponteiros:– cada elemento do vetor armazena o endereço

do primeiro elemento de cada linha da matriz

Page 22: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Exercício 1• Implemente a função multiplicação de matriz

usando a abordagem de alocação dinâmica de matrizes (vetor de ponteiros)

• Multiplicação de matrizes:– entrada:

• matriz A de dimensão m x p• matriz B de dimensão p x n

– saída: matriz M de dimensão m x n, definida como:

para i = 0 até m - 1, de 1 em 1 para j = 0 até n - 1, de 1 em 1 M[ i , j ] = 0 para k = 0 até p - 1, de 1 em 1 M[ i , j ] = M[ i , j ] + A[ i , k ] * B[ k , j ]

Page 23: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Resposta 1) Alocação

float **matrix( row, col )int row, col;{ float **a = NULL; int i, j;

a = (float**) malloc( row * sizeof(float*) ); if( a == NULL ) { fprintf(stderr,"\nProblema de alocacao !!!\n" ); return NULL; } for( i = 0; i < row; i++ ) { a[i] = (float*) malloc( col * sizeof(float) ); if( a[i] == NULL ) { printf("\nfprintf(stderr,"\nProblema de alocacao !!!\n" ); for( j = 0; j < i; j++ ) FREE( a[j] ); FREE( a ); return NULL; } } return a;}

Page 24: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Resposta 2) Liberação

#define FREE(ptr) if(ptr!=NULL){free(ptr);ptr=NULL;}

void matrix_free( M, row )float ***M;int row;{ int i;

if( (*M) == NULL ) return; if( row == 0 ) EXIT("matrix_free row=0");

for( i = 0; i < row; i++ ) FREE( (*M)[i] ); FREE( (*M) );}

ATENÇÃO: Variável M é modificada dentro da função ==> Passagem por referência. Como M é ponteiro para ponteiro, então passagem de ponteiro para ponteiro para ponteiro.

Page 25: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Resposta 3) Multiplicação

void matrix_mult( M1, row1, col1, M2, row2, col2, M3, row3, col3 )float **M1, **M2, ***M3;int row1, col1, row2, col2, *row3, *col3;{ int i, j, k; if( col1 != row2 ) { fprintf( stderr, "matrix_mult> Cannot multiply matrices"); fprintf( stderr, " (%d,%d) x (%d,%d). Exit...\n", row1, col1, row2, col2 ); exit(1); } *row3 = row1; *col3 = col2; matrix_free( M3, *row3 ); (*M3) = matrix( *row3, *col3 ); /* Multiply */ for( i = 0; i < *row3; i++ ) { for( j = 0; j < *col3; j++) { (*M3)[i][j] = 0.0; for( k = 0; k < col1; k++ ) (*M3)[i][j] += M1[i][k] * M2[k][j]; } }}

Page 26: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Resposta 4) Uso

extern float **matrix(); // pode ser incluído em arq. de cabeçalho (.h)

...

int linA, colA, linB, colB, linM, colM;float **A = NULL, **B=NULL, **M=NULL;...

A = matrix(linA,colA);B = matrix(linb,colB);…matrix_mult( A, linA, colA, B, linB, colB, &M, &linM, &colM );...matrix_free( &A, linA );matrix_free( &B, linB );matrix_free( &M, linM );

// Pós-condição: A==NULL, B==NULL, M==NULL, e memória liberada

Page 27: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Resposta

Page 28: Estruturas de Dados Aula 5: Matrizes 14/04/2014. Matrizes Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0]

Exercício 2

• Implemente a função multiplicação usando a abordagem de alocação dinâmica de matrizes (representada por vetor simples)

→ veja 'matrix.c'