278 lines
6.6 KiB
Java
278 lines
6.6 KiB
Java
/**
|
|
* Arvore binaria de pesquisa
|
|
* @author Max do Val Machado
|
|
*/
|
|
public class AVL {
|
|
private No raiz; // Raiz da arvore.
|
|
|
|
/**
|
|
* Construtor da classe.
|
|
*/
|
|
public AVL() {
|
|
raiz = null;
|
|
}
|
|
|
|
/**
|
|
* Metodo publico iterativo para pesquisar elemento.
|
|
* @param x Elemento que sera procurado.
|
|
* @return <code>true</code> se o elemento existir,
|
|
* <code>false</code> em caso contrario.
|
|
*/
|
|
public boolean pesquisar(int x) {
|
|
return pesquisar(x, raiz);
|
|
}
|
|
|
|
/**
|
|
* Metodo privado recursivo para pesquisar elemento.
|
|
* @param x Elemento que sera procurado.
|
|
* @param i No em analise.
|
|
* @return <code>true</code> se o elemento existir,
|
|
* <code>false</code> em caso contrario.
|
|
*/
|
|
private boolean pesquisar(int x, No i) {
|
|
boolean resp;
|
|
if (i == null) {
|
|
resp = false;
|
|
|
|
} else if (x == i.elemento) {
|
|
resp = true;
|
|
|
|
} else if (x < i.elemento) {
|
|
resp = pesquisar(x, i.esq);
|
|
|
|
} else {
|
|
resp = pesquisar(x, i.dir);
|
|
}
|
|
return resp;
|
|
}
|
|
|
|
/**
|
|
* Metodo publico iterativo para exibir elementos.
|
|
*/
|
|
public void caminharCentral() {
|
|
System.out.print("[ ");
|
|
caminharCentral(raiz);
|
|
System.out.println("]");
|
|
}
|
|
|
|
/**
|
|
* Metodo privado recursivo para exibir elementos.
|
|
* @param i No em analise.
|
|
*/
|
|
private void caminharCentral(No i) {
|
|
if (i != null) {
|
|
caminharCentral(i.esq); // Elementos da esquerda.
|
|
System.out.print(i.elemento + " "); // Conteudo do no.
|
|
caminharCentral(i.dir); // Elementos da direita.
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Metodo publico iterativo para exibir elementos.
|
|
*/
|
|
public void caminharPre() {
|
|
System.out.print("[ ");
|
|
caminharPre(raiz);
|
|
System.out.println("]");
|
|
}
|
|
|
|
/**
|
|
* Metodo privado recursivo para exibir elementos.
|
|
* @param i No em analise.
|
|
*/
|
|
private void caminharPre(No i) {
|
|
if (i != null) {
|
|
System.out.print(i.elemento + "(fator " + (No.getNivel(i.dir) - No.getNivel(i.esq)) + ") "); // Conteudo do no.
|
|
caminharPre(i.esq); // Elementos da esquerda.
|
|
caminharPre(i.dir); // Elementos da direita.
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Metodo publico iterativo para exibir elementos.
|
|
*/
|
|
public void caminharPos() {
|
|
System.out.print("[ ");
|
|
caminharPos(raiz);
|
|
System.out.println("]");
|
|
}
|
|
|
|
/**
|
|
* Metodo privado recursivo para exibir elementos.
|
|
* @param i No em analise.
|
|
*/
|
|
private void caminharPos(No i) {
|
|
if (i != null) {
|
|
caminharPos(i.esq); // Elementos da esquerda.
|
|
caminharPos(i.dir); // Elementos da direita.
|
|
System.out.print(i.elemento + " "); // Conteudo do no.
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Metodo publico iterativo para inserir elemento.
|
|
* @param x Elemento a ser inserido.
|
|
* @throws Exception Se o elemento existir.
|
|
*/
|
|
public void inserir(int x) throws Exception {
|
|
raiz = inserir(x, raiz);
|
|
}
|
|
|
|
/**
|
|
* Metodo privado recursivo para inserir elemento.
|
|
* @param x Elemento a ser inserido.
|
|
* @param i No em analise.
|
|
* @return No em analise, alterado ou nao.
|
|
* @throws Exception Se o elemento existir.
|
|
*/
|
|
private No inserir(int x, No i) throws Exception {
|
|
if (i == null) {
|
|
i = new No(x);
|
|
|
|
} else if (x < i.elemento) {
|
|
i.esq = inserir(x, i.esq);
|
|
|
|
} else if (x > i.elemento) {
|
|
i.dir = inserir(x, i.dir);
|
|
|
|
} else {
|
|
throw new Exception("Erro ao inserir!");
|
|
}
|
|
|
|
return balancear(i);
|
|
}
|
|
|
|
|
|
/**
|
|
* Metodo publico iterativo para remover elemento.
|
|
* @param x Elemento a ser removido.
|
|
* @throws Exception Se nao encontrar elemento.
|
|
*/
|
|
public void remover(int x) throws Exception {
|
|
raiz = remover(x, raiz);
|
|
}
|
|
|
|
/**
|
|
* Metodo privado recursivo para remover elemento.
|
|
* @param x Elemento a ser removido.
|
|
* @param i No em analise.
|
|
* @return No em analise, alterado ou nao.
|
|
* @throws Exception Se nao encontrar elemento.
|
|
*/
|
|
private No remover(int x, No i) throws Exception {
|
|
|
|
if (i == null) {
|
|
throw new Exception("Erro ao remover!");
|
|
|
|
} else if (x < i.elemento) {
|
|
i.esq = remover(x, i.esq);
|
|
|
|
} else if (x > i.elemento) {
|
|
i.dir = remover(x, i.dir);
|
|
|
|
// Sem no a direita.
|
|
} else if (i.dir == null) {
|
|
i = i.esq;
|
|
|
|
// Sem no a esquerda.
|
|
} else if (i.esq == null) {
|
|
i = i.dir;
|
|
|
|
// No a esquerda e no a direita.
|
|
} else {
|
|
i.esq = maiorEsq(i, i.esq);
|
|
}
|
|
|
|
return balancear(i);
|
|
}
|
|
|
|
|
|
/**
|
|
* Metodo para trocar o elemento "removido" pelo maior da esquerda.
|
|
* @param i No que teve o elemento removido.
|
|
* @param j No da subarvore esquerda.
|
|
* @return No em analise, alterado ou nao.
|
|
*/
|
|
private No maiorEsq(No i, No j) {
|
|
|
|
// Encontrou o maximo da subarvore esquerda.
|
|
if (j.dir == null) {
|
|
i.elemento = j.elemento; // Substitui i por j.
|
|
j = j.esq; // Substitui j por j.ESQ.
|
|
|
|
// Existe no a direita.
|
|
} else {
|
|
// Caminha para direita.
|
|
j.dir = maiorEsq(i, j.dir);
|
|
}
|
|
return j;
|
|
}
|
|
|
|
|
|
private No balancear(No no) throws Exception {
|
|
if(no != null){
|
|
int fator = No.getNivel(no.dir) - no.getNivel(no.esq);
|
|
|
|
//Se balanceada
|
|
if (Math.abs(fator) <= 1){
|
|
no.setNivel();
|
|
|
|
//Se desbalanceada para a direita
|
|
}else if (fator == 2){
|
|
|
|
int fatorFilhoDir = No.getNivel(no.dir.dir) - No.getNivel(no.dir.esq);
|
|
|
|
//Se o filho a direita tambem estiver desbalanceado
|
|
if (fatorFilhoDir == -1) {
|
|
no.dir = rotacionarDir(no.dir);
|
|
}
|
|
no = rotacionarEsq(no);
|
|
|
|
//Se desbalanceada para a esquerda
|
|
}else if (fator == -2){
|
|
|
|
int fatorFilhoEsq = No.getNivel(no.esq.dir) - No.getNivel(no.esq.esq);
|
|
|
|
//Se o filho a esquerda tambem estiver desbalanceado
|
|
if (fatorFilhoEsq == 1) {
|
|
no.esq = rotacionarEsq(no.esq);
|
|
}
|
|
no = rotacionarDir(no);
|
|
|
|
}else{
|
|
throw new Exception("Erro fator de balanceamento (" + fator + ") invalido!");
|
|
}
|
|
}
|
|
|
|
return no;
|
|
}
|
|
|
|
private No rotacionarDir(No no) {
|
|
System.out.println("Rotacionar DIR(" + no.elemento + ")");
|
|
No noEsq = no.esq;
|
|
No noEsqDir = noEsq.dir;
|
|
|
|
noEsq.dir = no;
|
|
no.esq = noEsqDir;
|
|
|
|
no.setNivel();
|
|
noEsq.setNivel();
|
|
|
|
return noEsq;
|
|
}
|
|
|
|
private No rotacionarEsq(No no) {
|
|
System.out.println("Rotacionar ESQ(" + no.elemento + ")");
|
|
No noDir = no.dir;
|
|
No noDirEsq = noDir.esq;
|
|
|
|
noDir.esq = no;
|
|
no.dir = noDirEsq;
|
|
|
|
no.setNivel();
|
|
noDir.setNivel();
|
|
return noDir;
|
|
}
|
|
}
|