Faculdade de Engenharia da Universidade do Porto
Licenciatura em Engenharia Electrotécnica e de Computadores
Algoritmos e Estruturas de Dados, 1998/99

Resolução de Prova de Avaliação:

//pergunta 3, Exame de Recurso, 1998/99, MTA

template<class T>
bool SimilarTree(BinaryTree<T> & tree1, BinaryTree<T> & tree2)
{
  return Semelhantes(tree1.root,tree2.root);
}

template<class T>
bool Semelhantes(BinaryTreeNode<T>* t1, BinaryTreeNode<T>* t2)
{
  if(!t1 && !t2) return true;    // duas 'arvores vazias (condicao i do enunciado)
  if(t1 && t2)
    return Semelhantes(t1->LeftChild,t2->LeftChild) && Semelhantes(t1->RightChild,t2->RightChild);
  else return false;
}

Nota: estas duas funcções, no sendo membros da classe BinaryTree, teriam que ser declaradas como funções "amigas" dessa classe para poderem utilizar os membros-dado privados das classes BinaryTree e BinaryTreeNode.

//pergunta 4, Exame de Recurso, 1998/99, MTA

Apresentam-se 3 abordagens possíveis para a resolução do problema:

1) supondo que temos todos os pontos disponíveis no mesmo instante:

1.1) estruturas de dados a utilizar:
   - lista linear com representação em array para guardar todos os pontos - "listaGeral".
   - lista linear em array (ou ligada) de listas ligadas para os clusters - "listaDeClusters".
 
Cada cluster é uma lista ligada cujo 1o. elemento se situa em listaDeClusters[j]; cada posição das listas deve conter três campos numericos para armazenar as duas coordenadas (campos x e y do tipo T) e para armazenar a distancia do ponto 'a origem do sistema de eixos (campo "distancia-'a-origem" do tipo T). No caso da lista ligada, estes campos fazem parte do campo data;

1.2) algoritmo:
   - ordenar "listaGeral" por ordem nao decrescente com base no campo "distancia-'a-origem",  utilizando o algoritmo QuickSort;
   - criar a "listaDeClusters" com n posicoes e utilizar o indice j com 0 <= j <n para aceder a cada posicao dessa lista;
   - efectuar o seguinte ciclo de instrucoes, iniciando na posicao 0 da "listaGeral" e acabando na ultima posicao n-1 (utilizando o indice i com 0 <= i <n):
     {
      - ler o campo "distancia-'a-origem" do elemento i;
      - se se tratar do 1o. elemento (i=0) armazenar esse ponto na 1a. posicao da "listaDeClusters"
        ( listaDeClusters[0].data.x = listaGeral[0].x; ...);
      - se ja' nao for o 1o. elemento (i!=0), comparar os campos "distancia-'a-origem" do elemento i em analise e do elemento (i-1);
        {
          - se a diferenca entre os dois valores for inferior 'a distancia de referencia, criar um novo no' na lista ligada (acrescentar um no' ao cluster j);
          - se a diferenca for maior, avancar para a posicao seguinte da "listaDeClusters" (j++) e guardar a informacao relativa ao ponto em analise no novo cluster.
        }
     }
1.3) complexidade temporal:
   - O(log(n)) para a ordenacao;
   - O(n) para o agrupamento em clusters (cada ponto so' tem que ser comparado com o seu vizinho anterior).

2)
Se nao for feita a ordenacao do conjunto inicial de pontos, pode utilizar as mesmas estruturas de dados embora nao necessite do campo "distancia-'a-origem". O algoritmo sera': - criar duas variaveis do tipo int, i e j, inicializadas a zero. Essas duas variaveis serao utilizados como indices para aceder a cada posicao da lista geral, listaGeral[i], e da lista de clusters, listaDeClusters[j]. Executar o seguinte ciclo enquanto i<length(listaGeral):
     {
      - colocar listaGeral[i] em listaDeClusters[j];
      - executar o seguinte ciclo para cada ponto k do cluster j, enquanto existirem pontos no cluster j: (necessita criar um apontador de no inicializado com o endereco do cluster j, i. e., com o valor (ListaDeClusters+j); o ciclo termina quando o apontador de no' for nulo)
         {
           - calcular a distancia entre o ponto k e cada ponto de listaGeral; se a distancia entre os dois for inferior 'a distancia de referencia:
              {
               - colocar esse ponto da listaGeral num novo no' do cluster j;
               - apagar (com a funcao Delete) esse elemento da listaGeral;
              }
         }
      - incrementar i;
      - incrementar j;
     }

3)  caso em que os pontos nao estao todos disponiveis no instante em que o programa arranca. Supoe-se que os pontos vao sendo recebidos e processados um a um.

1) estruturas de dados:
   - objecto constituido por dois campos do tipo T para guardar as coordenadas do ponto;
   - lista ligada de listas duplamente ligadas para implementar o conjunto de clusters;
     Cada campo data da lista ligada tem que ser um no' para conter um campo data e um apontador para o no' seguinte. Cada no' da lista ligada constitui o 1o. no' de cada cluster.
2) algoritmo:
   - enquanto existirem dados na entrada:
     {
       - cada ponto recebido tem que ser comparado com todos os pontos que ja' se encontram  armazenados em clusters; se se verificar que a distancia do ponto recebido a um ponto ja' armazenado num cluster e' inferior 'a distancia de referencia:
          - se for a 1a. vez que isso acontece, cria um novo no' no cluster que estava a analisar e continua a comparar com os outros pontos de todos os
clusters;
          - se for a segunda ou mais vezes que se verifica isso, entao junta num so' os clusters a que pertencem os pontos para os quais isso se verificou;
     }


[Página da disciplina] [J. Pascoal Home page] [J. Lopes Home page]
João Pascoal de Faria ([email protected]) / João Correia Lopes (jlopes AT fe.up.pt)
Last modified: Wed Jun 14 10:55:17 2000