Arvore Java

Então, estou tentando implementar uma arvore em java, porem não tá inserindo as palavras, é uma arvore de palavras e usei o metodo compareTo pra ver qual palavra vem antes,
mas na hora de inserir ta repetindo palavras, não sei se o problema é no método de inserção ou na hora de chamar a árvore. Se puderem ajudar, vou agradecer

A classe Arvore

public class ArvoreJava {  
   public static No raiz; // o único campo de dado em Arvore  
   

   public ArvoreJava() { // construtor  
     raiz = null;  //nenhum nó na arvore  
   } 
public static No insere(String palavra, No no) {  //metodo insere
        
        if(no == null){
            no = new No(palavra);  //se nao existir nó cria um novo
        }
        
        else if((compare(palavra, no.palavra)) < 0){ // faz comparação, se palavra
            no.filhoEsquerda = ArvoreJava.insere( palavra , no.filhoEsquerda);// menor que nó, insere na esquerda
        }
        else if((compare(palavra, no.palavra)) > 0){//se palavra maior que nó, insere na direita
           no.filhoDireita = ArvoreJava.insere(no.palavra, no.filhoDireita);
        }
        else{// senão, palavra já contem
            System.out.println("ERRO: valor já existe na árvore.");
            return null;
        }
        
        return no;

}
 public static void caminhando(ArvoreJava arv){//caminha na arvore 
                System.out.println("Pré-ordem: ");
		arv.preordem(arv.raiz);
     
 }
 public static int compare(String palavra, String no){ // compara strings e retorna um inteiro
     return palavra.toString().compareTo(no.toString());//-1 menor, 1 maior, 0 iguais
 }
 
 
        public  void preordem(No no)	{//caminha em preordem
            if (no == null){
		return;
		}
	System.out.println(no.palavra);
	preordem(no.filhoEsquerda);
	preordem(no.filhoDireita);
	}


}

A classe nó


package arvore;

public class No {
         
     String palavra;    //dado
     No filhoEsquerda; //cria filho  a esquerda
     No filhoDireita;  // cria filho a direita

    public No(String palavra){
		this.palavra = palavra;
	}
        
     public void mostraNo(){   
       {   
              
             System.out.print(palavra);   
             System.out.print(", ");   
               
        }   
     }   
   }

e aqui a parte do main

package arvore;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;


public class Arvore {
      
    public static void main(String[] args) {
        ArvoreJava arv = new ArvoreJava(); //instancia nova arvore
     
       Scanner ler = new Scanner(System.in); // scanea o arquivo txt
 
    System.out.printf("Informe o nome de arquivo texto:\n"); //abre arquivo txt
    String nome = ler.nextLine();
 
    System.out.printf("\nConteúdo do arquivo texto:\n");
    try {
      FileReader arq = new FileReader(nome);
      BufferedReader lerArq = new BufferedReader(arq);
      
      String str;
      List<String> palavras = new ArrayList<String>();
      int i = 0;
      
      String linha = lerArq.readLine(); // lê a primeira linha
// a variável "linha" recebe o valor "null" quando o processo
// de repetição atingir o final do arquivo texto
      
      
      
      while (linha != null) { // enquanto linha for diferente de null
          StringTokenizer st = new StringTokenizer(linha, " ");
          //st.nextToken();
          System.out.printf("%s\n", linha); // escreve a palavra na tela
        while(st.hasMoreTokens())   
        {  
            palavras.add(st.nextToken() + " ");  
        }  
          
          
       
        linha = lerArq.readLine(); // lê da segunda até a última linha
        
        
      }
      System.out.printf("\n");
      System.out.printf("\n");
      System.out.printf("\n");
       
            int j;
            String aux;
      
       for(String string : palavras){
           //aux = ;
           arv.raiz = arv.insere((String)palavras.get(i), arv.raiz);
           i++;
       }
        System.out.printf("\n");
        System.out.printf("\n");
        System.out.printf("\n");
        System.out.println("Ordenado em arvore:");
            
            
       
       arv.caminhando(arv); //chama o metodo de caminha na arvore
      
      arq.close();
    } catch (IOException e) {
        System.err.printf("Erro na abertura do arquivo: %s.\n",
          e.getMessage());
    }
 
    System.out.println();   
        
    }
   
}

Acho q o problema é nesse for para inserir a palavra, pois debugando vi q ta pegando as palavras antes de entrar nesse for

 for(String string : palavras){
           //aux = ;
           arv.raiz = arv.insere((String)palavras.get(i), arv.raiz);
           i++;
       }

Vc tá iterando de forma estranha aí…

Ou vc usa

for (String string : palavras){  
   arv.raiz = arv.insere(string, arv.raiz);  
}  

Ou

for(i = 0; i < palavras.size(); i++){  
   arv.raiz = arv.insere(palavras.get(i), arv.raiz);  
 }  

também não sei se isso é de seu interesse , mas seria melhor segmentar mais esse método main, tem muita informação, sem formatação etc.
Crie mais métodos e chame no main fica mais fácil de visualizar.
Valeu

Posta os métodos de inserção e da impressão da árvore.

Então

Esse é o de inserção

public static No insere(String palavra, No no) {  //metodo insere
        
        if(no == null){
            no = new No(palavra);  //se nao existir nó cria um novo
        }
        
        else if((compare(palavra, no.palavra)) < 0){ // faz comparação, se palavra
            no.filhoEsquerda = ArvoreJava.insere( palavra , no.filhoEsquerda);// menor que nó, insere na esquerda
        }
        else if((compare(palavra, no.palavra)) > 0){//se palavra maior que nó, insere na direita
           no.filhoDireita = ArvoreJava.insere(palavra, no.filhoDireita);
        }
        else if(palavra.equals(no.palavra)){// senão, palavra já contem
            System.out.println("ERRO: valor já existe na árvore.");
            return null;
        }
        
        return no;

Chamo ele no main assim:

for(String string : palavras){
           //aux = ;
           arv.raiz = arv.insere(string, arv.raiz);
           
       }

E esse é o de impressão com o pre ordem, quando imprime não imprime em ordem ,

public static void caminhando(ArvoreJava arv){//caminha na arvore 
                System.out.println("Pré-ordem: ");
		arv.preordem(arv.raiz);
     
 }
 

 
 
        public  void preordem(No no)	{//caminha em preordem
            if(no != null){
                System.out.println(no.palavra);
                preordem(no.filhoEsquerda);
                preordem(no.filhoDireita);
            }
            
            else if (no == null){
		return;
	    }
	
	}

Obg.

[quote=Luizao]Vc tá iterando de forma estranha aí…

Ou vc usa

for (String string : palavras){  
   arv.raiz = arv.insere(string, arv.raiz);  
}  

Ou

for(i = 0; i < palavras.size(); i++){  
   arv.raiz = arv.insere(palavras.get(i), arv.raiz);  
 }  

[/quote]

Valeu, mudei isso, mas ainda imprime fora de ordem
tenho essas palavras no meu txt

Conteúdo do arquivo texto:
java
aula
programar
metodo
main
classe

E ta imprimindo assim:

Ordenado em arvore:
Pré-ordem:
java
aula
classe
programar
metodo
main

[quote=Fellipex]também não sei se isso é de seu interesse , mas seria melhor segmentar mais esse método main, tem muita informação, sem formatação etc.
Crie mais métodos e chame no main fica mais fácil de visualizar.
Valeu[/quote]

Então, é poq fico louco programando, depois que acabar vou formatar bunitim, apagar mta coisa comentada e etc.

Acho que seu problema é de conceito e não de implementação. Você fez um método que se chama pré-ordem e ele faz exatamente isso. Não é papel do pré-ordem imprimir o conteúdo dos nós em ordem.

Para imprimir em ordem, você precisa utilizar o algoritmo de caminhamento em-ordem, Pesquise por “pré-ordem, em-ordem, pós-ordem” que você encontrará onde precisa mudar o seu método que imprime pré-ordem, para imprimir em-ordem. É apenas trocar uma linha de lugar.

Abs

[quote=regis_hideki]Acho que seu problema é de conceito e não de implementação. Você fez um método que se chama pré-ordem e ele faz exatamente isso. Não é papel do pré-ordem imprimir o conteúdo dos nós em ordem.

Para imprimir em ordem, você precisa utilizar o algoritmo de caminhamento em-ordem, Pesquise por “pré-ordem, em-ordem, pós-ordem” que você encontrará onde precisa mudar o seu método que imprime pré-ordem, para imprimir em-ordem. É apenas trocar uma linha de lugar.

Abs[/quote]

Você nao achou, vc tinha certeza, rsrs
deu certim aqui, foi só trocar a linha de lugar mesmo, valeu, agora vou dar uma limpada no código