[Resolvido] Duvida, ao retornar valor da subtracao da arvore

10 respostas
olivercld
Olá a todos, vou postar o codigo se alguem puder me esclarecer agradeço, nesse ultimo metodo para retornar o maior valor e o menor valor seria dessa forma que fiz? mais quando vou chamar no principal na main nao consigo.
package Arvore;

public class arvore {
	private No raiz;// somente a classe vaiter acesso

	public int maior = 0;// inicializa o atributo maior

	public int menor = 99999;// inicializao do menor

	// construtor
	public arvore() {
		raiz = null;

	}

	// metodo para altura
	public int altura(No raizLocal) {
		if (raizLocal == null)
			return 0;// a altura de 'nada' é zero
		int he = altura(raizLocal.filhoEsquerda);
		int hd = altura(raizLocal.filhoDireita);

		if (he < hd)
			return hd + 1;
		else
			return he + 1;

	}

	// metodo insere
	/**
	 * este metodo insere na arvore os no
	 */
	public void inserir(No novoNo) {

		if (raiz == null) {// se raiz for igual null nao tem nenhum no
			raiz = novoNo;// cria umnovo no

		} else {
			No atual = raiz;// atual e onde estou, armazena raiz
			No pai;// e o no pai e para saber onde vaiser inserido um outro no
			while (true) {// enquando a posicao do valor for verdadeira
				pai = atual;// guarda a variavel anterior, guarda a raiz que
				// esta a raiz
				// if para saber para onde eu vou, esquerda
				if (novoNo.chave < atual.chave) {// chave e por onde vai ser
					// organizado
					atual = atual.filhoEsquerda;// meu no atual acessa filho a
					// esquerda
					if (atual == null) {// se caso meu filho a esquerda da raiz
						// for null
						pai.filhoEsquerda = novoNo;// a variavel pai que
						// armazenou a raiz cria um
						// novo no
						return;

					}

				} else {// else para direita
					atual = atual.filhoDireita;
					if (atual == null) {
						pai.filhoDireita = novoNo;
						return;
					}

				}
			}

		}

	}

	/**
	 * metodo travessia nos permite escolher qual a forma que usaremos para
	 * percorrer todos os nós da arvore
	 */
	public void travessia(int tipoTravessia) {
		switch (tipoTravessia) {
		case 1:
			System.out.println("\n Travessia usando preOrder: ");
			preOrder(raiz);
			break;

		case 2:
			System.out.println("\n Travessia usando inOrder ");
			inOrder(raiz);
			break;

		case 3:
			System.out.println("\n Travessia usando posOrder: ");
			posOrder(raiz);
			break;

		}// fim do switch

	}// fim do metodo travessia()

	/**
	 * todos os nós sao visitados em ordem crescente metodo para inserir em
	 * Ordem
	 * 
	 * @param raizLocal
	 */
	public void inOrder(No raizLocal) {
		if (raizLocal != null) {// se raizLocal nao for igual a null
			inOrder(raizLocal.filhoEsquerda);// metodo inOrder aponta para
												// filho
			// a esquerda
			raizLocal.imprimirNo();// metodo acessa ou chama o metodo imprime
			inOrder(raizLocal.filhoDireita);// filho a direita
		}

	}// fimdometodo

	/**
	 * visita o nó chama a si mesmo para percorrer a subarvore a esquerda do
	 * nó chama a si mesmo para percorrer a subarvore a direita do nó
	 */
	private void preOrder(No raizLocal) {
		if (raizLocal != null) {// se raizLocal nao for igual a null
			preOrder(raizLocal.filhoEsquerda);// metodo inOrder aponta para
			// filho
			// a esquerda
			raizLocal.imprimirNo();// metodo acessa ou chama o metodo imprime
			preOrder(raizLocal.filhoDireita);// filho a direita
		}
	}

	// metodo posOrder
	private void posOrder(No raizLocal) {
		if (raizLocal != null) {
			posOrder(raizLocal.filhoEsquerda);
			posOrder(raizLocal.filhoDireita);
			raizLocal.imprimirNo();
		}
	}

	public boolean Deletar(int chave) {
		No atual = raiz;
		No pai = raiz;
		boolean eFilhoEsquerda = true;
		// o laco while e usado para encontrar o no a ser apagado
		// caso nao exista o nó,o laco retorna falso
		while (atual.chave != chave) {
			pai = atual;
			if (chave < atual.chave) {// vai para esquerda ou
				eFilhoEsquerda = true;
				atual = atual.filhoEsquerda;

			} else {// vai para direita
				eFilhoEsquerda = false;
				atual = atual.filhoDireita;

			}
			if (atual == null) {// fim dalinha ?
				return false; // nao encontrou valor da arvore
			}

		}
		// se o no a ser apagado nao possui filhos, simplesmente
		// o eliminado
		if (atual.filhoDireita == null && atual.filhoEsquerda == null) {
			// se elenao tem nenhum filho
			if (atual == raiz) {
				raiz = null;
			}
			// entra nesse lado o no esquerdo e apagado
			else if (eFilhoEsquerda) {
				pai.filhoEsquerda = null;
				// se entrar no else aqui o no apagado esta a direita
			} else {
				pai.filhoDireita = null;
			}
		}
		// se o nó a ser apagado possuir um filho direita
		else if (atual.filhoDireita == null) {
			if (atual == raiz) {
				raiz = atual.filhoDireita;
			} else if (eFilhoEsquerda) {
				pai.filhoDireita = atual.filhoEsquerda;
			} else {
				pai.filhoDireita = atual.filhoDireita;
			}
		}
		// se o no a ser apagado possuir umfilho a esquerda
		// substitui pela subarvore á direita
		else if (atual.filhoEsquerda == null) {
			if (atual == raiz) {
				raiz = atual.filhoDireita;
			} else if (eFilhoEsquerda) {
				// filho a esquerda do pai
				pai.filhoEsquerda = atual.filhoDireita;

			} else {
				// filho a direita do pai
				pai.filhoDireita = atual.filhoDireita;
			}

		}
		// se o no a ser apagado possuir dois filhos,
		// substituimos o no a ser apagado pelo seu seu sucessor
		// sucessor inOrder
		else {
			No sucessor = getSucessor(atual);
			// conectar o pai atual ao sucessor
			if (atual == raiz) {
				raiz = sucessor;
			} else if (eFilhoEsquerda) {
				pai.filhoEsquerda = sucessor;

			} else {
				pai.filhoDireita = sucessor;
			}
			// conecta o sucessor ao filho a direita
			sucessor.filhoDireita = atual.filhoDireita;

		}// fim do else dois filhos
		return true;
	}// fim do metodo deletar

	/**
	 * 
	 * @param atual
	 * @return o sucessor do Nó (atual) que queremos apagar
	 */

	private No getSucessor(No atual) {// apagar o no atual
		No sucessorPai = atual;
		No sucessor = atual;
		while (atual != null) {
			sucessorPai = sucessor;
			sucessor = atual;
			atual = atual.filhoEsquerda;// vai para filho a esquerda

		}
		// se o sucesor nao e filho a direita faz conexao
		if (sucessor != atual.filhoDireita) {
			sucessorPai.filhoDireita = sucessor.filhoDireita;
			sucessor.filhoDireita = atual.filhoDireita;
		}

		return sucessor;
	}

	// metodo para que retorna resultado da subtracao do maior pelo menor
	// elementos de uma árvore binária.
	public int SubDaArvore(No locaraiz ) {
		if (locaraiz != null) {
			//se a raiz local for diferente de nulo, continua
			SubDaArvore(locaraiz.filhoEsquerda);
			//anda para o lado esquerdo da arvore,
			
			if (maior < locaraiz.chave) {
				//se o maior for menor que o valor do Nó
				maior = locaraiz.chave;
				//o maior irá receber o valor que tem nesse Nó,caso
				//seje maior que maior.

			}
			if(menor > locaraiz.chave){
				//se menor for maior que o valor do Nó atual
				menor = locaraiz.chave;
				//menor recebe o valor do Nó atual.
			}
			//passos para o lado direito
			if(locaraiz != null){
				//se raiz locar nao for nulo
				SubDaArvore(locaraiz.filhoDireita);
				//caminha para lado direito da arvore
				
			}
			if(maior < locaraiz.chave){
				//se o maior for menor que o valor do No locar
				maior = locaraiz.chave;//armazena o valor
			}
			if(menor > locaraiz.chave){
				//se menor for maior que o valor do Nó atual
				menor = locaraiz.chave;
				//o menor armazena este valor
			}
			

			

		}
		return maior - menor;
		
		
	}
}
package Arvore;

public class TesteArvore {
	public static void main(String[] args) {
		arvore arvore1 = new arvore();
		
		
		// arvore1.inOrder(no2);

		System.out.println("Subtracao do maior pelo menor valor da arvore:" );
		arvore1.SubDaArvore(locaraiz);

	}

}
qual é o meu erro ?

10 Respostas

E

Só pra te encher o saco, lembre-se que nomes de packages devem ficar em minúsculas e nomes de classes começam por maiúsculas. Então você deveria ter “package arvore;” e “class Arvore;”

De qualquer forma, não é melhor você criar um método que determina qual é o maior elemento, outro que determina qual é o menor, e então chamar a diferença desses valores? É mais fácil de entender, principalmente quando você usa métodos recursivos.
Do jeito que você fez, ficou muito complicado e não estou conseguindo entender direito o que você fez.
Primeiro, faça funcionar, e depois veja se dá para otimizar.
Fazer já otimizado, logo de cara, dá muitos problemas.
Em particular, acho estranho você desprezar o valor de retorno do método recursivo dentro do método recursivo. É muito esquisito.

olivercld

ok entanglement esqueci desse fato que tu disse do pacote e a classe, bom vou tentar mais uma vez e volto a postar caso nao consiga, valeu obrigado.

olivercld

bom apos varias pesquisas, no wiki, teve uma explicação sobre, bom eu atraves do exemplo dado fiz aqui, por gentileza entanglement se puder me orientar no restante, eu tenho de fazer a subtração agora na main certo, eu faria algo como arvore1. chamo o metodo do maior - arvore1. metodo do menor ?

public int informaMaior(No locaraiz) { if (locaraiz != null) { if(maior < locaraiz.chave) maior = locaraiz.chave;//maior recebe valor, do No atual this.informaMaior(locaraiz.filhoEsquerda); //anda pelo lado esquerdo da arvore, em busca do maior this.informaMaior(locaraiz.filhoDireita); //anda para o lado direito, em busca do maior return maior; }else return 0; } //procurar o menor public int informaMenor(No locaraiz) { if (locaraiz != null) { if(menor > locaraiz.chave)//obvio que vai ser maior, entao menor = locaraiz.chave;//menor recebe valor, do No atual this.informaMenor(locaraiz.filhoEsquerda); //anda pelo lado esquerdo da arvore, em busca do maior this.informaMenor(locaraiz.filhoDireita); //anda para o lado direito, em busca do maior return menor; }else return 0; }

E

Que salada, não faça recursividade mútua (que é o que você tentou fazer).
Se você quer usar recursividade mútua, então aprenda a recursividade simples primeiro.
Em vez disso, faça algo como (nem olhei seu código, só estou dando uma espécie de pseudo-código: )

public int acharMinimo (No raiz) {
    int minimoEsquerdo = valor maximo de um inteiro;
    int minimoDireito = valor maximo de um inteiro;
    if (raiz.esquerdo != null)
        minimoEsquerdo = acharMinimo (raiz.esquerdo);
    if (raiz.direito != null)
        minimoDireito = acharMinimo (raiz.direito);
    if (raiz.esquerdo == null && raiz.direito == null) return raiz.valor;
    return Math.min (minimoEsquerdo, minimoDireito);
}
olivercld

ok, entanglement este pseudo-código, desse metodo que voce mostrou ele é para achar o minimo no caso, menor valor tanto no lado direito como no lado esquerdo ? ou no caso terei de fazer um desse para valor minimo e outro metodo para valor maximo ?

E

Agora que você entendeu, não é? É isso mesmo. Crie 2 métodos, e ache a diferença.
Eu sei, eu sei, eu sei que você poderia simplesmente varrer todos os elementos da árvore (usando varredura por profundidade ou por largura, não importa) e achar o máximo e o mínimo de uma vez só, como você tentou fazer.
Mas acho que é mais fácil dividir o problema em 2 em vez de tentar fazer tudo otimizado logo de cara.
Resolva o problema primeiro, e depois, vendo como é que ele foi resolvido, tente otimizá-lo , se possível.
Ninguém acerta as coisas logo de cara (mesmo Deus descansou no 7º dia, mas depois teve de lançar um “service pack”, ou seja, fez o Dilúvio e encarregou Noé de dar um jeito nas coisas. Acho que está na hora de lançar o Service Pack 2 :slight_smile:

olivercld
certo e no caso eu posso iniciar

int minimoEsquerdo = 9999;

int minimoDireito = 9999;

como fiz para iniciar o menor?

olivercld

acho que entendi, vou implementar aqui, e nada que la por 4 da manhã retorno dizendo duvida ou resolvido hehehe.
obrigado até agora entanglement aguarde já retornarei para te incomodar hehe

olivercld

entanglement desculpe te incomodar,mais não estou tendo sucesso ao chamar ao fazer a subtração da alguns erros.

olivercld

ainda ocorrendo erros.]

int a = acharMaior - acharMenor;
System.out.println(" Subtracao: "+a);

também não da certo.
Criado 22 de novembro de 2011
Ultima resposta 25 de nov. de 2011
Respostas 10
Participantes 2