Template , Java , BST oraz przekazywaniem argumentów

0

Witam.

Tworzę drzewo poszukiwań binarnych w Javie i mam następujące problemy:

  1. Mam problem z tworzeniem korzenia. Mianowicie przekazuję np 3 razy argumenty kolejno:
    addtree(2,root);
    addtree(1,root);
    addtree(3,root);
    i niestety za każdym razem mimo że przekazuję root w argumencie to on widzi mi go jako null, i nie mam zielonego pojęcia dlaczego tak się dzieje.

Drugi problem jest taki że nie bardzo wiem jak w takim template gdzie mam <T> sprawdzić czy T jest Integerem , Stringiem bądź innym typem danych (Potrzebuję sprawdźić ze względu na sortowanie drzewa). Problem jest taki że o ile nawet już jestem w stanie sobie to sprawdzić za pomocą danej którą również przekazuje (tj sprawdzam jakiego jest typu) to nie mogę żadnych działań typu Data2<xyz.Data1 gdyż nie mogę porównywać ze sobą zmiennych T(czyli nie określonych). Próbowałem to obejść dodając przed danymi (Int) i.t.p ale nie pomogło to wcale.

Prosiłbym gorąco o pomoc w zrozumieniu tych problemów i ich rozwiązanie , gdyż sam jestem już bezsilny (Za wiele informacji na temat tych problemów na internecie nie mogłem znaleźć , zwłaszcza z moim słabym angielskim :(

class tree_tamplate <T>{
    public Node root;

    private class Node {
        public Node left,right;
        public T Data1;
    }

    public void addTree(T Data2,Node xyz){

           
            if(xyz!=null){
                if(Data2 instanceof Integer){
                    if(Data2 < xyz.Data1){
                        addTree(Data2,xyz.left);
                    }
                    else if(Data2 > xyz.Data1){
                        addTree(Data2,xyz.right);
                    }
                }
                else{
                    if(Data2.charAt(0)<xyz.Data1.charAt(0)){
                        xyz.left=new Node();
                        addTree(Data2,xyz.left);
                    }
                    else if(Data2.charAt(0)>xyz.Data1.charAt(0)){
                        xyz.right=new Node();
                        addTree(Data2,xyz.right);
                    }

                }
            }
            else if (xyz==null){
                xyz=new Node();
                xyz.Data1=Data2;

            }
        }
    } 

Z góry dziękuję za pomoc

1
  1. Bo przypisanie wartości do tej referencji przekazanej jako argument do metody NIE ZMIENI tego na co pokazuje referencja poza funkcją. Jako argument przekazywana jest kopia referencji do obiektu! Zresztą nie bardzo rozumiem po co w ogóle tak robisz skoro w tej klasie masz już pole root i zwyczajnie powinieneś z niego skorzystać ;]
  2. W ogole nie powinieneś niczego takiego sprawdzać bo i po co? o_O Po to robisz <T> żeby móc operować na dowolnych klasach. A jak będę chciał użyć twojego drzewa dla obiektów mojej własnej klasy to bedę musiał zmieniać twój kod? Gdzie tu sens? Powinieneś mieć tam parametr który implementuje interfejs z metodą której użyjesz do porównywania. Na przykład:
interface Cmp<T>{
  boolean isGreater(T first, T second);
}

class Tree<T extends Cmp<T>>{

}

I teraz możesz sobie porównywać za pomocą metody isGreater() wszystkie typy <T> które implementują intefejs Cmp. Oczywiscie java już posiada taki intefejs i nazywa się on Comparable<T>
Więc powinieneś mieć

class TreeTemplate<T extends Comparable<T>>{
//
}
0
Shalom napisał(a):
  1. Bo przypisanie wartości do tej referencji przekazanej jako argument do metody NIE ZMIENI tego na co pokazuje referencja poza funkcją. Jako argument przekazywana jest kopia referencji do obiektu! Zresztą nie bardzo rozumiem po co w ogóle tak robisz skoro w tej klasie masz już pole root i zwyczajnie powinieneś z niego skorzystać ;]
  2. W ogole nie powinieneś niczego takiego sprawdzać bo i po co? o_O Po to robisz <T> żeby móc operować na dowolnych klasach. A jak będę chciał użyć twojego drzewa dla obiektów mojej własnej klasy to bedę musiał zmieniać twój kod? Gdzie tu sens? Powinieneś mieć tam parametr który implementuje interfejs z metodą której użyjesz do porównywania. Na przykład:
interface Cmp<T>{
  boolean isGreater(T first, T second);
}

class Tree<T extends Cmp<T>>{

}

I teraz możesz sobie porównywać za pomocą metody isGreater() wszystkie typy <T> które implementują intefejs Cmp. Oczywiscie java już posiada taki intefejs i nazywa się on Comparable<T>
Więc powinieneś mieć

class TreeTemplate<T extends Comparable<T>>{
//
}

Dzięki Ogromne za pomoc (Prawdopodobnie nawet nie wiesz jak bardzo mi pomogłeś). Mimo wszystko mam jeszcze jedno pytanko. Czy jest sens robić takie drzewo rekurencją (Tj dodawanie do drzewa), czy lepiej zrobić to za pomocą while(true)? W ogóle pytanie czy da radę zrobić dodawanie rekurencyjne w takim drzewie w javie?

1

Rekurencja bardzo rzadko jest dobrym rozwiązaniem ;)

0

No tak , ale np do drukowania takiego drzewa od wartości najmniejszej do największej rekurencja sprawdziła by się świetnie (a przynajmniej tak mi się wydaje). I tu np wydaje mi się że dobry mógłby być kod taki public void printTree(Node nprint) {

    if(nprint.left!=null){
        printTree(nprint.left);
    }
    System.out.println(nprint.Data1);

    if(nprint.right!=null){
        printTree(nprint.right);
    }

}
 
Tyle że znowu teraz mam problem z przekazaniem korzenia na początku (Chyba że bym wywołał jakąś inną metodę w tej klasie TreeTamplate , która by mi przekazała korzeń do metody printTree i wtedy raczej problemu z korzeniem by nie było...tylko pytanie czy to dobry sposób na rozwiązanie tego problemu).

Ps. jeszcze raz dziękuję za pomoc i poświęcenie swojego czasu :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1