Implementierung von Bäumen



  • Guten Abend

    Ich suche Seiten, Turotials, ect über Bäume.

    Habe schon was gefunden, doch bei den Seiten war die Anzahl der Elemente immer Gleich,
    der Baum, welche ich brauche, weiss die Anzahl der Neuen Elemente erst beim aufruf (1-10 neue Elemente). Irgendwie steh ich momentan auf dem Schlauch und weis nicht wie weiter.

    Aktuelles Element   (weiss erst beim aufruf des konstruktors wieviele "neue" element Vorliegen)
               /    |   \ 
              /     |    \
             /      |     \
            Ele1   Ele2   Ele3
    

    thx im voraus

    gruss reima



  • denke nicht das es sowas schon gibt



  • class Tree
    {
      Tree *branches = new Tree[i]; // i = anzahl äste an diesem knoten
      int value;
    }
    


  • template<class T>
    struct treenode
    {
    treenode *parent;
    std::vector<treenode*> childs; // variabel ohne Ende
    T data;
    };
    

    Und? Was ist da jetzt so schwierig dran? Einfach std::vector für variable Childs benutzen.



  • ich halte einen vector da für etwas overhead. Die implementierung mit dem stinknormalen Array reicht da vollkommen aus...



  • Strange das Ganze stürtz ab Wegen Overflow im vector... dabei habe ich doch speicher reserviert dafür (mit resize) 😕 😕

    #include <iostream>
    #include <vector>
    using namespace std;
    
    // ein Element///////////////////////////////////////////////
    class Element
    {
    public:
    	int anz_Elemente;
    	vector<Element*> NextElement;
    	Element(int anz);
    	Element();
    	void Init(int anz);//Anzahl der Elemente Festlegen
    
    	int Wert;
    
    private:
    };
    // K O N S T R U K T O R  ////////////////////////////////////////////////////////////////
    Element::Element()
    {
    	anz_Elemente = 0;
    }
    Element::Element(int anz)
    {
    	vector<Element*> NextElement(anz);
    	NextElement.resize(NextElement.size()+anz);
    	anz_Elemente = NextElement.capacity();
    }
    
    // M E T H O D E N //////////////////////////////////////////////////////////////////////////
    void Element::Init(int anz)
    {
    	vector<Element*> NextElement(anz);
    	NextElement.resize(NextElement.size()+anz);
    	anz_Elemente = NextElement.capacity();
    
    }
    
    ////////////////////////////////////////////////////////////////////////////////
    
    class Baum
    {
    public:
    	// K O N S T R U K T O R E N 
    	Baum(int wert,int anz);
    	Baum();
    
    	////////////////////////////////////////
    	int GetNextElement(int choise);
    	void SetNextEleVaule(int choise,int vaule);
    	Element Kopf;
    	//////////////////////////////////////////
    
    };
    // K O N S T R U K T O R E N /////////////////////////////////////////////////////////////
    Baum::Baum()
    {
    }
    Baum::Baum(int wert,int anz)
    {
    
    	Kopf.Init(anz);
    	Kopf.Wert =wert;
    }
    ///////////////////////////////////////////////////////////////////////////////////////////
    
    int Baum::GetNextElement(int choise)
    {
    
    	if((choise <= Kopf.anz_Elemente)&&(choise >= 0))
    	{
    
    		return( Kopf.NextElement.at(choise)->Wert);
    	}
    	return 0;
    
    }
    void Baum::SetNextEleVaule(int choise,int vaule)
    {
    
    	if((choise <= Kopf.anz_Elemente)&&(choise >=0))
    	{	
    
    		Kopf.NextElement.at(choise)->Wert = vaule;
    	}
    }
    int main()
    {	
    	Baum tests(33,33);
    	tests.SetNextEleVaule(3,33); // <---- hier stürtz das programm ab!!!!
    	cout<<tests.GetNextElement(2);
    
    	return 0;
    


  • ich würds mit vector.push_back probieren. ist ja nicht umsonst nen selbst organisierendes System..
    btw: das nennt sich choice 😉



  • schau mal hier.



  • Oh mein Gott! 😃

    Der vector kennt doch seine Anzahl der Elemente, mußt du nirgends vermerken. Weiterhin mußt du mit push_back(myElement) die Elemente anfügen. Dann resized sich der Vector von ganz alleine.

    Abstürzen kann der vector auch nicht, da er bei Fehlern Ausnahmen wirft, die du abfangen kannst und solltest.

    Schau mal hier die Infos (besonders Kapitel 2.1) zum Vector, damit du damit besser umgehen kannst :
    http://www.kharchi.de/cppratgeber2.htm



  • ich hätte da mehrere Dinge zu beanstanden:
    Erstens:

    Element::Element(int anz)
    {
        vector<Element*> NextElement(anz);
    

    hier definierst du innerhalb der Methode einen neuen vector namens "NextElement", der wegen Namensgleichkeit die Membervariable gleichen Namens überdeckt. Nicht überschreibt oder sowas, sondern einfach nur unsichtbar werden lässt. Du führst also in deinem Konstruktor bzw. deiner Init() ein paar Befehle auf einer lokalen Variable aus, die direkt danach wieder verschwindet. Könntest den Methodenrumpf gleich leer lassen...
    Der Konstruktor ruft also für deine Membervariable NextElement einfach implizit den Standardkonstruktor auf (vector<Element*>()). Danach wird NextElement nie wieder geändert. Mit at() greifst du weter unten also auf Bereiche zu, die garnicht existieren.

    Zweitens:
    Du benutzt keine Initialisierungslisten. Wäre aber eleganter und erspart dir überflüssige Konstruktoraufrufe.

    Drittens:
    Du hast in der Klasse Baum eine Membervariable namens Kopf public gemacht. Sowas tut man einfach nicht, das ist schlechter Stil. Machs private und biete, falls nötig, Zugriffsmethoden an.

    Soviel fürs erste, genauer angeguckt hab ichs mit nicht.



  • pumukl schrieb:

    ch hätte da mehrere Dinge zu beanstanden:
    Erstens:
    C/C++ Code:
    Element::Element(int anz)
    {
    vector<Element*> NextElement(anz);
    C/C++ Code:
    Element::Element(int anz)
    {
    vector<Element*> NextElement(anz);
    C/C++ Code:
    Element::Element(int anz)
    {
    vector<Element*> NextElement(anz);
    hier definierst du innerhalb der Methode einen neuen vector namens "NextElement"

    Danke, genau hier lag der fehler, und deshalb wurde auch die Exeption ausgelöst:

    hier mal die bearbeitete Klasse:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    // ein Element///////////////////////////////////////////////
    class Element
    {
    public:
    
    	vector<Element> NextElement;
    
    	Element();
    	~Element();
    
    	int Wert;
    
    private:
    };
    // K O N S T R U K T O R  ////////////////////////////////////////////////////////////////
    Element::Element()
    {
    	Wert = 0;
    }
    Element::~Element()
    {
    
    }
    
    ////////////////////////////////////////////////////////////////////////////////
    
    class Baum
    {
    public:
    	// K O N S T R U K T O R E N 
    	Baum(int wert,int tiefe);
    	Baum(int tiefe);
    	////////////////////////////////////////
    
    	//Aktuelle Tiefe 
    	int GetAktTiefe(){return aktTiefe;}
    
    	//Äste vor oder zurück 
    	void AddTiefe(int Add)
    	{
    		if((Add + aktTiefe < maxTiefe)&& (aktTiefe + Add >= 0))
    			aktTiefe+=Add;
    	}
    
    	Element GetNextElement(int choice);
    	void SetNextEleVaule(int vaule);
    
    	//////////////////////////////////////////
    
    private:
    	vector<Element> Kopf;
    	int maxTiefe;
    	int aktTiefe;	
    };
    // K O N S T R U K T O R E N /////////////////////////////////////////////////////////////
    Baum::Baum(int tiefe)
    {
    	Kopf.resize(Kopf.size()+tiefe);
    	maxTiefe = tiefe;
    	aktTiefe = 0;
    }
    Baum::Baum(int wert,int tiefe)
    {
    	Kopf.resize(Kopf.size()+tiefe);
    	Kopf.at(0).Wert =wert;
    	maxTiefe = tiefe;
    	aktTiefe = 0;
    }
    ///////////////////////////////////////////////////////////////////////////////////////////
    
    Element Baum::GetNextElement(int choice)
    {
    		return( Kopf.at(aktTiefe).NextElement.at(choice));	
    }
    void Baum::SetNextEleVaule(int vaule)
    {
    
    		Element NewElement;
    		NewElement.Wert = vaule;
    		Kopf.at(aktTiefe).NextElement.push_back(NewElement);
    }
    

    Jetzt besser so??


Anmelden zum Antworten