Árvore Binária

Dei uma procurada no guj e não encontrei nada que me ajudasse ou que fosse pelo menos parecido … !

seguinte, estou estudando árvore binária ( ainda … :roll: ) e estou tentando fazer um método que me retorne o sucessor de um Nó … por exemplo …

se eu passar a chave 10, eu preciso encontrar a menor chave maior que 10.

é preciso usar recursividade ?

eis o Nó :

[code] public static class NO
{
Registro reg;
NO direito;
NO esquerdo;

    /** Cria novos Objetos da Classe NO */
    public NO (Registro r)
    {
        reg = r;
        direito = null;
        esquerdo = null;
    }
}[/code]

É possível fazer sem recursividade…

Vc deve ter alguma classe que controla a inclusão e remoção nessa árvore…

posta ai pra gente…

(só lembrando que, em Java não temos “ponteiro”, pra quem vem da linguagem C, como eu, pode encontrar dificuldades pra trabalhar com estrutura de dados… mas é só amadurecer o conceito de orientação a objetos e tudo se resolve…)

att,
Paulo Henrique

Criei estes dois métodos para inserir … ( e apanhei bastante … não estou muito abituado a pensar recursivamente ! :? )

[code]public void insere(Registro r)
{
this.raiz = this.insere(r,raiz);
}

private NO insere( Registro r,NO p)
{
    
    if ( p==null )
    {
        p = new NO(r);
        p.esquerdo = null;
        p.direito = null;
    }
    
    else if ( r.chave <p.reg.chave)
    {
        p.esquerdo = insere(r, p.esquerdo);
    }
    
    else if (r.chave>p.reg.chave)
    {
        p.direito = insere(r,p.direito);
    }
    
    else 
        System.out.println("Registro ja existe");
    
    return p;
}[/code]

e estes para remover

[code]public void retira (Registro r)
{
this.raiz = this.retira(r,this.raiz);
}

private NO retira ( Registro r , NO p )
{
    if ( p==null )
    {
        System.out.println("Registro nao encontrado");
    }
    
    if(r.chave <p.reg.chave)
    {
        p.esquerdo = retira(r,p.esquerdo);
    }
    
    else if (r.chave>p.reg.chave)
    {
        p.direito = retira(r,p.direito);
    }
    
    else 
    {
        if ( p.direito == null )
        {
            p=p.esquerdo;
        }
    
        else if ( p.esquerdo == null )
        {
            p=p.direito;
        }
        
        else
        {
            p.esquerdo = antecessor(p,p.esquerdo);
        }
     }

    return p;
}[/code]

vou te ajudar…
aguarda uma meia hora ai… ja te mostro um código…

eu cheguei a fazer um método mas tive problemas quando o Nó era uma folha …

o nó no meu código não possui a referência para “NÓ PAI” portanto pensei em

  • pesquisar pela chave
  • a partir da raiz buscar o sucessor

até agora só funciona se a chave estiver na subárvore direita … !
vou continuar tentando aqui !

Fiz aqui agora, não ficou muito bonito não, isso pode ser melhorado muito…

public class No {
	
	private int elemento;
	private No dir, esq;

	public No(int elemento){
		
		this.elemento = elemento;
		dir = null;
		esq = null;
	}
	
	public int getElemento(){
		return elemento;
	}
	
	public No getDir(){
		return dir;
	}
	
	public void setDir(No dir){
		this.dir = dir;
	}
	
	public No getEsq(){
		return esq;
	}
	
	public void setEsq(No esq){
		this.esq = esq;
	}
}
public class Arvore {

	No raiz;
	No atual;

	public Arvore() {
		raiz = null;
	}

	public No getRaiz(){
		return raiz;
	}
	
	public void insereNO(No no) {

		if (raiz == null) {
			raiz = no;
		} else {
			atual = raiz;
			while (atual != null) {

				if (no.getElemento() &lt atual.getElemento()) {
					if (atual.getEsq() == null) {
						atual.setEsq(no);
						break;
					}
					else 
						atual = atual.getEsq();
					
				} else if (no.getElemento() &gt atual.getElemento()) {
					if (atual.getDir() == null) {
						atual.setDir(no);
						break;
					}else 
						atual = atual.getDir();
				}else{
					System.out.println("Elemento já existe na árvore!!!");
					return;
				}
			}
		}
	}
	
	public void imprimeArvore(No no) {

		if (no == null)
			return;
		
		System.out.println(no.getElemento() + " ");

		imprimeArvore(no.getEsq());
		imprimeArvore(no.getDir());
	}
}
public class Main {

	public static void main(String[] args) {

		Arvore arvore;
		No no;

		arvore = new Arvore();
		no = new No(10);
		arvore.insereNO(no);
		no = new No(5);
		arvore.insereNO(no);
		no = new No(15);
		arvore.insereNO(no);
		no = new No(12);
		arvore.insereNO(no);

		arvore.imprimeArvore(arvore.getRaiz());
	}

}

nos testes que eu fiz funcionou…

agora fica o desafio pra vc… implementar a remoção…

lembre-se que a remoção do nó raiz terá um tratamento diferenciado…

att,
Paulo Henrique

acho que você não entendeu muito bem a pergunta …
o que vc me passou já tá pronto …

eu precisava de um método que me retorne o sucessor de um dado nó …

[quote]seguinte, estou estudando árvore binária ( ainda … ) e estou tentando fazer um método que me retorne o sucessor de um Nó … por exemplo …

se eu passar a chave 10, eu preciso encontrar a menor chave maior que 10. [/quote]

valeu pela força de qualquer forma !
:wink:

eu entendi a pergunta sim cara…

mas isso é tão intuitivo…

se vc tem um no…

seria algo do tipo…

no.getDir();
no.getEsq();

isso são sucessores de um nó…

suponha a seguinte árvore :

… 10
… /…
… 1 …11
…/… …
… 0 … 9 …19
… /…\
…14…21
… …
…18…30

o sucessor do NO 18 seria o NO 19
o sucessor do NÓ 0 seria o NÓ 1
o sucessor de 9 seria 10 …

não tô enxergando de jeito nenhum como encontrar esse nó sucessor dado um determinado nó …

me dá 10 minutos…

cara… jeito eu encontrei… não é muito eficiente… mas… resolve…

O algoritmo é o seguinte:

Percorre a arvore inteira, a partir da raiz… e pega todos os elementos que são maior do que o elemento que vc deseja achar o sucessor…
Vc coloca esses caras numa lista ou num vetor… ai é só pegar o menor deles, que o mesmo é o sucessor!!!

	public void sucessor(No autal, No elem){
		
		if (atual == null)
			return;
		
		if(atual.getElemento() &gt elem.getElemento()){
			//insere o elemento atual.getElemento numa lista, ou num     vetor...	
		}
		sucessor(atual.getEsq(), elem);
		sucessor(atual.getDir(), elem);
	}

espero ter ajudado…

bom,

é um caminho diferente no qual eu não havia pensado ! realmente não é muito eficiente mas já resolve o meu problema !

deve ter algum jeitinho de resolver isso usando recursividade , !

valeu pela força cara ! :wink:
vou implementar sua solução aqui !

Exemplo:

Tenho a seguinte árvore e desejo encontrar o sucessor do 12.

…10
…5…15
…2…12…16
…17
…20

Neste caso, eu teria a seguinte lista/vetor:
15 -&gt 16 -&gt 17 -&gt 20

Percorro a lista, e pego o menor elemento!!!

[quote=ph_ms]cara… jeito eu encontrei… não é muito eficiente… mas… resolve…

O algoritmo é o seguinte:

Percorre a arvore inteira, a partir da raiz… e pega todos os elementos que são maior do que o elemento que vc deseja achar o sucessor…
Vc coloca esses caras numa lista ou num vetor… ai é só pegar o menor deles, que o mesmo é o sucessor!!!

	public void sucessor(No autal, No elem){
		
		if (atual == null)
			return;
		
		if(atual.getElemento() &gt elem.getElemento()){
			//insere o elemento atual.getElemento numa lista, ou num     vetor...	
		}
		sucessor(atual.getEsq(), elem);
		sucessor(atual.getDir(), elem);
	}

espero ter ajudado…[/quote]

é por aí mesmo, mas pra economizar memória acho que jah pode fazer a comparação direto e nem precisa armazenar no vetor. A lógica é pegar o menor número maior que 18 por exemplo. Então pega o primeiro, 50 por exemplo, dai o próximo é 20, descarta o 50 e fica com o 20, dai o próximo é 30, nem pega ele, dai o próximo é 19…dai pega! e por aí vai!

é… realmente não é uma maneira viável não…

mas sem usar um nó pro PAI do elemento, fica mais difícil de achar o sucessor…

só mais uma dica…é meio óbvia mas…

se vc procura o sucessor de N, então quando encontrar N+1 jah pode parar de procurar, que é ctz que esse é o sucessor!! :smiley:

desculpa se é meio óbvio…

o sucessor de N, pode não ser N + 1, pode ser N + 2… N + N… enfim…