Sim, você pode executar essa compactação em , mas não é fácil :) Primeiro fazemos algumas observações e depois apresentamos o algoritmo. Assumimos que a árvore inicialmente não seja compactada - isso não é realmente necessário, mas facilita a análise.O ( n logn )
Primeiramente, caracterizamos indutivamente a "igualdade estrutural". Seja e T ′ duas (sub) árvores. Se T e T ' são ambas as árvores nulas (sem vértices), elas são estruturalmente equivalentes. Se T e T ' não são árvores nulas, elas são estruturalmente equivalentes se seus filhos esquerdos forem estruturalmente equivalentes e seus filhos direitos forem estruturalmente equivalentes. 'Equivalência estrutural' é o ponto fixo mínimo sobre essas definições.TT′TT′TT′
Por exemplo, quaisquer dois nós de folha são estruturalmente equivalentes, pois ambos têm as árvores nulas como seus filhos, que são estruturalmente equivalentes.
Como é bastante irritante dizer 'seus filhos esquerdos são estruturalmente equivalentes e também os filhos certos', freqüentemente diremos 'seus filhos são estruturalmente equivalentes' e pretendem o mesmo. Observe também que às vezes dizemos 'este vértice' quando queremos dizer 'a subárvore enraizada nesse vértice'.
A definição acima imediatamente nos dá uma dica de como realizar a compactação: se conhecermos a equivalência estrutural de todas as subárvores com profundidade no máximo , então podemos calcular facilmente a equivalência estrutural das subárvores com profundidade d + 1 . Precisamos fazer esse cálculo de maneira inteligente para evitar um tempo de execução de O ( n 2 ) .dd+ 1O ( n2)
O algoritmo atribuirá identificadores a todos os vértices durante sua execução. Um identificador é um número no conjunto . Os identificadores são únicos e nunca mudam: portanto, assumimos que definimos alguma variável (global) como 1 no início do algoritmo e, toda vez que atribuímos um identificador a algum vértice, atribuímos o valor atual dessa variável ao vértice e incrementamos o valor dessa variável.{ 1 , 2 , 3 , … , n }
Primeiro, transformamos a árvore de entrada em (no máximo ) listas contendo vértices de igual profundidade, juntamente com um ponteiro para o pai. Isso é feito facilmente em O ( n ) tempo.nO ( n )
Primeiro compactamos todas as folhas (podemos encontrá-las na lista com vértices de profundidade 0) em um único vértice. Atribuímos a esse vértice um identificador. A compactação de dois vértices é feita redirecionando o pai de um dos vértices para apontar para o outro vértice.
Fazemos duas observações: primeiro, qualquer vértice tem filhos de profundidade estritamente menor e, segundo, se tivermos realizado compressão em todos os vértices de profundidade menores que (e os tivermos identificado), então dois vértices de profundidade d são estruturalmente equivalentes e podem ser compactados se os identificadores de seus filhos coincidirem. Essa última observação segue o seguinte argumento: dois vértices são estruturalmente equivalentes se seus filhos são estruturalmente equivalentes e, após a compressão, isso significa que seus ponteiros estão apontando para os mesmos filhos, o que, por sua vez, significa que os identificadores de seus filhos são iguais.dd
Repetimos todas as listas com nós de igual profundidade, de pequena profundidade a grande profundidade. Para cada nível, criamos uma lista de pares inteiros, onde cada par corresponde aos identificadores dos filhos de algum vértice nesse nível. Temos que dois vértices nesse nível são estruturalmente equivalentes se seus pares inteiros correspondentes forem iguais. Usando a ordenação lexicográfica, podemos classificá-los e obter os conjuntos de pares inteiros iguais. Comprimimos esses conjuntos em vértices únicos, como acima, e os identificamos.
As observações acima provam que essa abordagem funciona e resulta na árvore compactada. O tempo total de execução é mais o tempo necessário para classificar as listas que criamos. Como o número total de pares inteiros que criamos é n , isso nos dá que o tempo total de execução é O ( n log n ) , conforme necessário. Contar quantos nós ainda restam no final do procedimento é trivial (basta ver quantos identificadores entregamos).O ( n )nO ( n logn )