Contato

  • Jean Paulo Martins (jeanmartins utfpr edu br)
  • Sala 105, Bloco S (UTFPR - Campus Pato Branco)

Comparação-plágio: abrir em outra página

Avaliação dos códigos-fonte

Sobre a complexidade da implementação Sobre o uso consistente de formatação

Avalie a complexidade do código abaixo para listas de encadeamento simples e duplo!

void list_print(list* v) {
	int cont = 0;
	node* aux = v->head;
	while(cont++<list_size(v))
	{
		printf("%d \n", aux->value);
		aux = aux->next;
	}
}

Com uma simples modificação baixamos a complexidade $O(n^2)$ para $O(n)$, ver abaixo:

void list_print(list* v) {
	int size = list_size(v);
	node* aux = v->head;
	while(size-- > 0) {
		printf("%d \n", aux->value);
		aux = aux->next;
	}
}

Simplificação de código

Observe se o uso de bibliotecas adicionais tornariam o código-fonte mais legível (fácil de compreender)

int list_empty(list* v) {
    if(v->head == NULL)
        return 1;
    else
        return 0;
}

O tipo de dados Booleanos é sempre mais indicado para escrita de códigos que envolvam resultados lógicos (verdadeiro/falso). Pois evidenciam o significado do retorno. Todas linguagens de programação “modernas” possuem esse tipo de dados.

#include <stdbool.h>
bool list_empty(list* v) {
    return v->head == NULL;
}

Formatação dos comentários

Comentários são úteis e devem ser utilizados, nos ajudam a compreender melhor o código e a relembrar posteriormente. No entanto, eles fazem parte do seu código-fonte e devem ser escritos/formatados corretamente.

int** new_matrix(int m, int n)
{
    int i,j;

    int **Matrix=(int**)malloc(m*sizeof(int*));//nesse passo eu aloquei um vetor de ponteiros.
    
    

    for(i=0;i<m;i++)//percorre as linhas.
    {
        Matrix[i]=(int*)malloc(n*sizeof(int));//aloca um vetor de inteiros para a coluna.
    }
    return Matrix;//Retorna o ponteiro para a matriz alocada.
}

A legibilidade é afetada pelo excesso de espaços e pelo fato dos comentários terem sido inseridos após o fim da linha. Se o comentário é extenso o indicado é escrevê-lo antes da operação.

O espaçamento entre os operadores também deixa o código mais organizado e fácil de ler.

Evite declarar índices no ínicio da função, isso pode ser feito na própria definição do loop.

int** new_matrix(int m, int n) {
    //nesse passo eu aloquei um vetor de ponteiros.
    int **Matrix = (int**) malloc (m * sizeof(int*));
    for(int i = 0; i < m; i++) {
        //aloca um vetor de inteiros para a coluna.
        Matrix[i] = (int*) malloc(n * sizeof(int));
    }
    //Retorna o ponteiro para a matriz alocada.
    return Matrix;
}

Comentários para funções

void list_push_front(list* v, Type value) 
{//Insere no inicio.
    list_insert(v,value,0);
}

Ao comentarmos a definição de uma função é usual utilizarmos comentários de múltiplas linhas e mais descritivos.

/*
 Insere  um novo nó de conteúdo `value` no início da lista.
 */
void list_push_front(list* v, Type value) {
    list_insert(v,value,0);
}

Indentação

Seja consistente com sua indentação. Se utiliza 4 espaços, 8 espaços ou tabulação, isso não é importante. Porém, utilize sempre o mesmo padrão em todo o seu arquivo.

Observe o tipo de retorno da sua função, se ela sempre retorna NULL, não há porque retornar algo.

int**free_matrix (int m, int n, int **v)
{
  int  i;
  if (v == NULL) return (NULL);
  if (m < 1 || n < 1) {
     printf (" erro");
     return (v);
     }
  for (i=0; i<m; i++)
    free (v[i]);

  free (v);
  return (NULL);
}
void free_matrix (int m, int n, int **v) {
    if (v != NULL) {
        for (int i = 0; i < m; i++)
            free (v[i]);
        free (v);
    }
}

Espaços fazem parte da linguagem e devem ser utilizados apropriadamente

node* iterate_to(list*v,int pos){
    assert(pos>0&&pos<=list_size(v));
    int indice = 0;
    node*ptr=v->head;

    while(indice++!=pos-1)
        ptr=ptr->next;
    return ptr;



}

O código acima se torna muito mais organizado e legível com a formatação apropriada (observe o assert)

node* iterate_to(list*v,int pos) {
    assert(pos > 0 && pos <= list_size(v));
    int indice = 0;
    node*ptr=v->head;
    while(indice++ != pos-1)
        ptr=ptr->next;
    return ptr;
}

Valores lógicos raramente precisam ser explicitados em comparações

Type list_pop_front(list* v){
    assert(list_empty(v)!=true);
    //...

Em casos como esse, o true pode ser ignorado sem prejuízo à interpretação do texto.

Type list_pop_front(list* v) {
    assert(list_empty(v));
    //...

O mesmo acontece no trecho abaixo:

if(list_empty(v) == true){ 

Que se mantém claro se escrito como “Se a lista v está vazia”

if(list_empty(v)) { 

Separe/modularize funcionalidades de uso recorrente!

A funcionalidade iterate_to foi definida para que fique claro a lógica que envolve inserção/remoção de nós. Sem que essa lógica se confunda com a lógica de programação para percorrer a lista.

Type list_erase(list* v, int i){
    Type valor;
    if(i<=0)
    {
        list_pop_front(v);
    }
    else if(i>=(list_size(v)-1))
    {
        list_pop_back(v);
    }
    else
    {
        int j=0;
        node* a=v->head;
        node* e;
        while(j!=(i-1))
        {
            a=a->next;
            j++;
        }
        e=a->next;
        valor=e->value;
        a->next=e->next;
        free(e);
    }
    return(valor);
}

Vejamos a simplificação do código acima adaptado para utilizar iterate_to.

Type list_erase(list* v, int i) {
    Type valor;
    if(i < = 0)
        list_pop_front(v);
    else if(i >= list_size(v) - 1)
        list_pop_back(v);
    else {
        node* a = iterate_to(v, i);
        node* e = a->next;
        valor = e->value;
        a->next = e->next;
        free(e);
    }
    return(valor);
}

Para simplificação do código, evite redundâncias

int list_size(list* v)
{
    int i=0;
    if(v->head!=NULL)
    {
       node* b=v->head;
       for(i=1;b->next!=NULL;i++)
       {
          b=b->next;
       }
    }
    return i;
}

A função acima funcionará normalmente se removermos o if inicial.

int list_size(list* v) {
    int size = 0;
    node* b = v->head;
    for(; b != NULL; size++)
      b = b->next;
    return size;
}