<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Binary Search Tree, Speicher wieder freiegeben]]></title><description><![CDATA[<p>hallo,</p>
<p>zur Uebung implementiere ich gerade einen Binaeren Suchbaum, jetzt versuche ich am Ende den Speicher moeglichst effizient freizugeben, dazu beuntze ich einen Stack, ist das die effektiviste Methode und ist der Code unten gut so und gibt er wirklich den ganzen Speicher wieder frei?</p>
<pre><code>~bstree()
	{

		if(root!=0)
		{
			std::stack&lt;Node*&gt;s;
			if(root-&gt;left!=0)s.push(root-&gt;left);
			if(root-&gt;right!=0)s.push(root-&gt;right);

			while(!s.empty())
			{
				Node *t = s.top();
				s.pop();
				if(t-&gt;left!=0)s.push(t-&gt;left);
				if(t-&gt;right!=0)s.push(t-&gt;right);
				std::cout &lt;&lt; &quot;Delete: &quot; &lt;&lt; t-&gt;data &lt;&lt; std::endl;
				delete t;

			};

		}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/320715/binary-search-tree-speicher-wieder-freiegeben</link><generator>RSS for Node</generator><lastBuildDate>Thu, 23 Jul 2026 18:37:59 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/320715.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 09 Oct 2013 09:00:42 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 09:00:42 GMT]]></title><description><![CDATA[<p>hallo,</p>
<p>zur Uebung implementiere ich gerade einen Binaeren Suchbaum, jetzt versuche ich am Ende den Speicher moeglichst effizient freizugeben, dazu beuntze ich einen Stack, ist das die effektiviste Methode und ist der Code unten gut so und gibt er wirklich den ganzen Speicher wieder frei?</p>
<pre><code>~bstree()
	{

		if(root!=0)
		{
			std::stack&lt;Node*&gt;s;
			if(root-&gt;left!=0)s.push(root-&gt;left);
			if(root-&gt;right!=0)s.push(root-&gt;right);

			while(!s.empty())
			{
				Node *t = s.top();
				s.pop();
				if(t-&gt;left!=0)s.push(t-&gt;left);
				if(t-&gt;right!=0)s.push(t-&gt;right);
				std::cout &lt;&lt; &quot;Delete: &quot; &lt;&lt; t-&gt;data &lt;&lt; std::endl;
				delete t;

			};

		}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2359054</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359054</guid><dc:creator><![CDATA[MigMig]]></dc:creator><pubDate>Wed, 09 Oct 2013 09:00:42 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 09:26:28 GMT]]></title><description><![CDATA[<p>Definiere effizient/effektiv.<br />
Root wird nicht gelöscht, ob data freigegeben wird, kann man dem Code nicht entnehmen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359060</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359060</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Wed, 09 Oct 2013 09:26:28 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 10:07:54 GMT]]></title><description><![CDATA[<p>Hier der ganze Code, root zu loeschen hatte ich vergessen. Mit Effektiv meine ich, ist es der gewoehnliche Ansatz einen Stack zu benutzen im den Speicher wieder freizugeben, oder geht das auch alles nur mit einem oder evtl. zwei Zeigern und gekonntem Zeigerhantierung?</p>
<pre><code>class bstree
{

public:

	bstree():root(0){};
	~bstree()
	{

		if(root!=0)
		{
			std::stack&lt;Node*&gt;s;
			if(root-&gt;left!=0)s.push(root-&gt;left);
			if(root-&gt;right!=0)s.push(root-&gt;right);
			delete root;

			while(!s.empty())
			{
				Node *t = s.top();
				s.pop();
				if(t-&gt;left!=0)s.push(t-&gt;left);
				if(t-&gt;right!=0)s.push(t-&gt;right);
				std::cout &lt;&lt; &quot;Delete: &quot; &lt;&lt; t-&gt;data &lt;&lt; std::endl;
				delete t;

			};

		}

	};
	void add(int data)
	{
		Node *new_node = new Node(data);
		if(root==0)
		{
			root = new_node;
		}
		else
		{
			Node *current = root;
			Node *parent;

			while(current!=0)
			{
				parent  = current;
				current = current-&gt;data &lt; data ? current-&gt;right : current-&gt;left;
			};
			if(data &gt; parent-&gt;data)
				parent-&gt;right = new_node;
			else
				parent-&gt;left = new_node;
		}

	};

private:
	class Node
	{
	public:
		Node(int d):data(d),left(0),right(0){};
		Node *left;
		Node *right;
		int data;
	};
	Node *root;

};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2359079</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359079</guid><dc:creator><![CDATA[MigMig]]></dc:creator><pubDate>Wed, 09 Oct 2013 10:07:54 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 10:23:40 GMT]]></title><description><![CDATA[<p>Auch &quot;gewöhnlich&quot; ist ein dehnbarer Begriff, aber gewöhnlich wird wohl ein Knoten dafür verantwortlich seine, seine Kinder zu löschen. Am einfachsten wird dies dann mit unique_ptr für left, right und root implementiert. Bei Bäumen mit langen Zweigen könnte einem da natürlich der Programmstack überlaufen, dann wäre dein Ansatz als Lösung durchaus &quot;üblich&quot;. Aber im Destruktor implementiert ist es dann auch nicht sinnvoll: was machst du, wenn du einen Knoten im Baum löschen willst?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359082</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359082</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Wed, 09 Oct 2013 10:23:40 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 11:56:19 GMT]]></title><description><![CDATA[<p>Warum nicht einfach rekursiv Loeschen. Per Tiefen-&quot;Suche&quot; zu den Blattknoten und beim rekursiven Aufstieg freigeben. Destruktoren zerstoeren, deiner baut aber erstmal einen Stack auf ... dabei kann eine Exception fliegen. Schlecht.</p>
<blockquote>
<p>Mit Effektiv meine ich, ist es der gewoehnliche Ansatz einen Stack zu benutzen im den Speicher wieder freizugeben</p>
</blockquote>
<p>Nein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359108</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359108</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 09 Oct 2013 11:56:19 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 12:03:17 GMT]]></title><description><![CDATA[<blockquote>
<p>Warum nicht einfach rekursiv Loeschen.</p>
</blockquote>
<p>Nun, besonders effizient ist das nicht, soweit ich mich erinnere.</p>
<p>Allerdings würde ein <code>unique_ptr</code> auch nur rekursiv löschen - er ruft (implizit) den Destruktor des Knotens auf. Dieser Destruktor zerstört aber auch die Member, unter denen sich wiederum zwei unique_ptrs befinden, deren Destruktor aufgerufen wird.</p>
<p>Das Problem ist, dass man irgendwie &quot;zurückkehren&quot; muss, zum Elternteil, um zum zweiten Knoten zu kommen, und dann wiederum muss man zurück zum Elternknoten dieses Knotens....</p>
<p>Den Elternteil muss man sich also merken.<br />
Also entweder ein Array, um sich alle höheren Verwandten zu merken, oder Rekursion (da werden die Zeiger automatisch 'zwischengespeichert'.<br />
Oder etwa nicht? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359115</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359115</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Wed, 09 Oct 2013 12:03:17 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 12:10:27 GMT]]></title><description><![CDATA[<blockquote>
<p>Nun, besonders effizient ist das nicht, soweit ich mich erinnere.</p>
</blockquote>
<p>Ja wo du das gerade so erwaehnst, da haette ich jetzt auch selbst drauf kommen koennen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<blockquote>
<p>... Den Elternteil muss man sich also merken</p>
</blockquote>
<p>Ja und so. Rekursion halt. Je nach Kenntnisstand hilft ein Buch ueber Algorithmen weiter.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359118</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359118</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 09 Oct 2013 12:10:27 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 13:54:23 GMT]]></title><description><![CDATA[<p>Ein Baum ist eine rekursive Datenstruktur <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Wieso also zwanghaft die Rekursion vermeiden.<br />
Die Suche im Baum läuft doch auch rekursiv <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359161</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359161</guid><dc:creator><![CDATA[MichelRT]]></dc:creator><pubDate>Wed, 09 Oct 2013 13:54:23 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 14:10:47 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>Warum nicht einfach rekursiv Loeschen.</p>
</blockquote>
<p>Nun, besonders effizient ist das nicht, soweit ich mich erinnere.</p>
</blockquote>
<p>Doch.</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Allerdings würde ein <code>unique_ptr</code> auch nur rekursiv löschen - er ruft (implizit) den Destruktor des Knotens auf. Dieser Destruktor zerstört aber auch die Member, unter denen sich wiederum zwei unique_ptrs befinden, deren Destruktor aufgerufen wird.</p>
<p>Das Problem ist, dass man irgendwie &quot;zurückkehren&quot; muss, zum Elternteil, um zum zweiten Knoten zu kommen, und dann wiederum muss man zurück zum Elternknoten dieses Knotens....</p>
<p>Den Elternteil muss man sich also merken.<br />
Also entweder ein Array, um sich alle höheren Verwandten zu merken, oder Rekursion (da werden die Zeiger automatisch 'zwischengespeichert'.<br />
Oder etwa nicht? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
</blockquote>
<p>Oder links und rechts merken. Oder nur links und rechts zur Schleife machen. Keine Ahnung, weshalb Du aufwärts gehen magst.</p>
<p>Rekursion halte ich hier für angemessen, wenn der Baum ausreichend balanciert ist, daß es nicht zum Stacküberlauf kommen kann. Dem Hardwarestack traue ich hier mehr Speed zu als einem Softwarestack.</p>
<p>MigMig schrieb:</p>
<blockquote>
<pre><code>~bstree()
    {
 
        if(root!=0)
        {
            std::stack&lt;Node*&gt;s;
            if(root-&gt;left!=0)s.push(root-&gt;left);
            if(root-&gt;right!=0)s.push(root-&gt;right);
           
 
            while(!s.empty())
            {
                Node *t = s.top();
                s.pop();
                if(t-&gt;left!=0)s.push(t-&gt;left);
                if(t-&gt;right!=0)s.push(t-&gt;right);
                std::cout &lt;&lt; &quot;Delete: &quot; &lt;&lt; t-&gt;data &lt;&lt; std::endl;
                delete t;
 
            };
   
        }
</code></pre>
</blockquote>
<p>Da haste eine komische Sonderbehandlung der root.</p>
<pre><code>~bstree()
    {
        if(root!=0)
        {
            std::stack&lt;Node*&gt;s;
            s.push(root);//reicht doch und root wird sogar auch gelöscht

            while(!s.empty())
            {
                Node *t = s.top();
                s.pop();
                if(t-&gt;left!=0)s.push(t-&gt;left);
                if(t-&gt;right!=0)s.push(t-&gt;right);
                std::cout &lt;&lt; &quot;Delete: &quot; &lt;&lt; t-&gt;data &lt;&lt; '\n';//kein endl
                delete t;
             }
        }
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2359168</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359168</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Wed, 09 Oct 2013 14:10:47 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 14:27:35 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>Warum nicht einfach rekursiv Loeschen. Per Tiefen-&quot;Suche&quot; zu den Blattknoten und beim rekursiven Aufstieg freigeben. Destruktoren zerstoeren, deiner baut aber erstmal einen Stack auf ... dabei kann eine Exception fliegen. Schlecht.</p>
</blockquote>
<p>Hmm.<br />
Genug Speicher ist eigentlich da…</p>
<pre><code>~bstree()
{
    if(!root) return;

    Node* rightmost=root;
    while(rightmost-&gt;right)
        rightmost=rightmost-&gt;right;

    while(root){
        Node* toDie=root;
        rightmost-&gt;right=root-&gt;left;
        while(rightmost-&gt;right)
            rightmost=rightmost-&gt;right;
        root=root-&gt;right;
        delete toDie;
    }
}
//ungetestet
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2359174</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359174</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Wed, 09 Oct 2013 14:27:35 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 14:52:09 GMT]]></title><description><![CDATA[<blockquote>
<p>Doch.</p>
</blockquote>
<p><a href="http://www.c-plusplus.net/forum/317985-full" rel="nofollow">Doch?</a><br />
Aber nicht so gut wie eine smarte Schleife, nicht wahr?</p>
<blockquote>
<p>Oder links und rechts merken. Oder nur links und rechts zur Schleife machen. Keine Ahnung, weshalb Du aufwärts gehen magst.</p>
</blockquote>
<p>Ich kam nicht direkt darauf, wie man es mit einer richtig hübschen Schleife mit O(1) Speicher, wie du es tust, lösen kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359181</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359181</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Wed, 09 Oct 2013 14:52:09 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 15:38:45 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>Doch.</p>
</blockquote>
<p><a href="http://www.c-plusplus.net/forum/317985-full" rel="nofollow">Doch?</a><br />
Aber nicht so gut wie eine smarte Schleife, nicht wahr?</p>
</blockquote>
<p>Das nervt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359197</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359197</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Wed, 09 Oct 2013 15:38:45 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 15:43:40 GMT]]></title><description><![CDATA[<blockquote>
<p>Das nervt.</p>
</blockquote>
<p>Was nervt?</p>
<p>Auch wenn Rekursion schnell ist, ist es schließlich doch nicht optimal. Und wieso etwas Suboptimales wählen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359198</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359198</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Wed, 09 Oct 2013 15:43:40 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 15:46:31 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>Doch.</p>
</blockquote>
<p><a href="http://www.c-plusplus.net/forum/317985-full" rel="nofollow">Doch?</a><br />
Aber nicht so gut wie eine smarte Schleife, nicht wahr?</p>
</blockquote>
<p>Was willste damit aussagen? Falls es das ist, was ich fürchte, haste die Speicherverwaltung nicht mitgerechnet? Es geht nicht darum, eine Zählschleife mit einer rekursion zu vergleichen, sondern es geht auch ums Zwischenspeichern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359199</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359199</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Wed, 09 Oct 2013 15:46:31 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 16:49:46 GMT]]></title><description><![CDATA[<blockquote>
<p>Auch wenn Rekursion schnell ist, ist es schließlich doch nicht optimal. Und wieso etwas Suboptimales wählen?</p>
</blockquote>
<p>Deine Behauptungen entbehren jeder Tatsache und sind schlicht falsch. Mit Rekursion wird jeder Knoten besucht, du musst alle Knoten besuchen deswegen kann es keinen schnelleren Algorithmus geben. Troll doch woanders.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359202</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359202</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 09 Oct 2013 16:49:46 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 16:22:38 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>Genug Speicher ist eigentlich da…</p>
<pre><code>~bstree()
{
    if(!root) return;
    
    Node* rightmost=root;
    while(rightmost-&gt;right)
        rightmost=rightmost-&gt;right;
    
    while(root){
        Node* toDie=root;
        rightmost-&gt;right=root-&gt;left;
        while(rightmost-&gt;right)
            rightmost=rightmost-&gt;right;
        root=root-&gt;right;
        delete toDie;
    }
}
//ungetestet
</code></pre>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f4a1.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--light_bulb"
      title=":bulb:"
      alt="💡"
    /> Daran hatte ich auch gedacht und dann verworfen, in der Annahme, dass es zu quadratischer worst-case-Komplexität führt. Aufgeschrieben ist aber klar zu erkenn, dass die Blattsuche niemals zweimal über den gleichen Knoten führt, ist also doch schön linear.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359208</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359208</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 09 Oct 2013 16:22:38 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 16:48:05 GMT]]></title><description><![CDATA[<p>Der Algorithmus hat glaube einen Bug. Oder vielleicht nicht, ich muss nochmal schauen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359215</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359215</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 09 Oct 2013 16:48:05 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 19:31:14 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f4a1.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--light_bulb"
      title=":bulb:"
      alt="💡"
    /></p>
</blockquote>
<p>Was mich wundert, ist, daß ich von diesem Trick noch nie auch nur andeutungsweise gelesen habe. Für praktisch eingesetzte Bäume, deren Tiefe man nicht garantieren kann, wie z.B. Spreizbäume, wäre das doch vielleicht eine Idee, zum Standardverfahren zu werden. Tragfähig ist das auf jeden Fall. Die Cache-Lokalität ist ein wenig doof.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359271</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359271</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Wed, 09 Oct 2013 19:31:14 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 20:26:01 GMT]]></title><description><![CDATA[<p>Nur ein kleiner Tip:<br />
Wenn man den Baum einfach nur aufbaut und dann verwendet, dazwischen aber keine Änderungen macht, dann kann man schön nen <code>std::vector&lt;Node&gt;</code> verwenden.<br />
Statt Zeiger hat man dann Vektor-Indizes.<br />
Damit sollte nicht nur das Freigeben sehr schnell gehen sondern auch das Aufbauen.<br />
Lookups werden ein wenig leiden, wegen der geringfügig aufwändigeren Adressierung der Nodes.</p>
<p>Bzw. wenn man keine stabilen Node-Iteratoren braucht kann man damit vermutlich sogar einen änderbaren Baum schön hinbekommen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359283</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359283</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 09 Oct 2013 20:26:01 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 20:55:05 GMT]]></title><description><![CDATA[<p>Du hast vor x mal operator delete aufzurufen und verdächtigst die rekursiven Aufrufe zu imperformant zu sein?<br />
Schau doch mal bitte erstmal nach wie lange ein delete braucht.</p>
<p>Wenn es wirklich performant sein soll dann muss man sowieso nen Pool für die Nodes verwenden und fickt nicht mit new/delete rum. Ein Pool bringt immerhin sauschnelle Allokation, optimale Cache-Lokalität und je nach Inhalt der Nodes auch sauschnelle Deallokation.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359290</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359290</guid><dc:creator><![CDATA[Ethon]]></dc:creator><pubDate>Wed, 09 Oct 2013 20:55:05 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 21:10:56 GMT]]></title><description><![CDATA[<p>Habs lokaler gekriegt (normalerweise).</p>
<pre><code>~bstree()
{
    if(!root) return;//einfach gut, weil doch viele 
        //Destruktor-Aufrufe auf einem leeren bstree geschehen. 
    Node* r=root;
    while(r){
        if(!r.left){//weg
            Node* toDie=r;
            r=r-&gt;right;
            delete toDie;
        }
        else if(!r.right){//weg
            Node* toDie=r;
            r=r-&gt;left;
            delete toDie;
        }
        else{//rotieren an der root! Die wird nämlich als nächstes bearbeitet. 
//Ist jetzt ein Stack statt einer Queue für die vertagten Jobs. 
//Gute Vermutung, daß Löschungen relativ nah nach Rotierungen kommen, 
//also der Mist noch im Cache ist. Perfekt für Bäume, die &quot;quasi&quot; ballanciert 
//sind, in normalen Anwendungsfällen &quot;quasi&quot; immer, aber man kann's 
//nicht garantieren. 
            Node* e=r-&gt;left-&gt;right;
            Node* newR=r-&gt;left;
            newR-&gt;right=r;
            r-&gt;left=e;
            r=newR;
        }
    }
}
//ungetestet
</code></pre>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359291</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359291</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Wed, 09 Oct 2013 21:10:56 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 21:09:49 GMT]]></title><description><![CDATA[<pre><code>if(!root) return;//einfach gut, weil doch viele
        //Destruktor-Aufrufe auf einem leeren bstree geschehen.
</code></pre>
<p>Aber dir ist doch sicher klar dass die logisch komplett äquivalente Abfrage 2 Zeilen darunter sowieso durchgeführt wird und das Ganze keinen Takt langsamer ist? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359295</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359295</guid><dc:creator><![CDATA[Ethon]]></dc:creator><pubDate>Wed, 09 Oct 2013 21:09:49 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Wed, 09 Oct 2013 21:27:50 GMT]]></title><description><![CDATA[<p>Ethon schrieb:</p>
<blockquote>
<pre><code>if(!root) return;//einfach gut, weil doch viele
        //Destruktor-Aufrufe auf einem leeren bstree geschehen.
</code></pre>
<p>Aber dir ist doch sicher klar dass die logisch komplett äquivalente Abfrage 2 Zeilen darunter sowieso durchgeführt wird und das Ganze keinen Takt langsamer ist? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
</blockquote>
<p>Uups!!!<br />
<img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /><br />
Wie offensichtlich!!!<br />
*lach*</p>
<p>Habe mich ums Rotieren gequält. Bäume sind nicht mein Ding eigentlich. Fast immer gibt es bessere Alternativen. War heldenfroh, es gepackt zu haben. Habe zwar sofort gesehen, daß es so möglich ist, Algos mögen mich irgendwie, aber die Reihenfolge der elemetaren Zuweisungen, nööö, da habe ich keine Intuition. Eher eine Drecksintuition. Hätte an der Hochschule bleiben müssen, damit Doktoranden für mich den lästigen Quark ausarbeiten. *hihi*</p>
<p>Produktivcode wäre das nicht bei mir geworden. Ich schaue mir immer was funktionierendes nochmal später an. Wobei ich dem gcc sogar zutraue, daß er das auch packt, der ist ein Monster.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359299</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359299</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Wed, 09 Oct 2013 21:27:50 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Thu, 10 Oct 2013 09:36:16 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>Wobei ich dem gcc sogar zutraue, daß er das auch packt, der ist ein Monster.</p>
</blockquote>
<p>Für den rb-tree jedenfalls nicht, da arbeitet der Algorithmus rekursiv (in-oder mit ausgeschriebener Tail-Rekursion). Da der Baum immer ausbalanciert ist, kann man hier Stacküberläufe ausschliessen. Wie es mit internen Datenstrukturen des Compilers aussieht, weiss ich nicht.</p>
<p>aus /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/stl_tree.h</p>
<pre><code class="language-cpp">template&lt;typename _Key, typename _Val, typename _KeyOfValue,
           typename _Compare, typename _Alloc&gt;
    void
    _Rb_tree&lt;_Key, _Val, _KeyOfValue, _Compare, _Alloc&gt;::
    _M_erase(_Link_type __x)
    {
      // Erase without rebalancing.
      while (__x != 0)
        {
          _M_erase(_S_right(__x));
          _Link_type __y = _S_left(__x);
          _M_destroy_node(__x);
          __x = __y;
        }
    }
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2359365</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359365</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 10 Oct 2013 09:36:16 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Thu, 10 Oct 2013 09:36:41 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>volkard schrieb:</p>
<blockquote>
<p>Wobei ich dem gcc sogar zutraue, daß er das auch packt, der ist ein Monster.</p>
</blockquote>
<p>Für den rb-tree jedenfalls nicht, da arbeitet der Algorithmus rekursiv. Da der Baum immer ausbalanciert ist, kann man hier Stacküberläufe ausschliessen. Wie es mit internen Datenstrukturen des Compilers aussieht, weiss ich nicht.</p>
</blockquote>
<p>Ich meinte, das dumme if wegzuoptimieren. Aus dem rekursiven Löschen soll er gar keine andere Version bauen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359368</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359368</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Thu, 10 Oct 2013 09:36:41 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Search Tree, Speicher wieder freiegeben on Thu, 10 Oct 2013 10:01:28 GMT]]></title><description><![CDATA[<p><s>Man kann das if auch funktional machen.</s> Wobei ich bezweifle, dass diese Optimierung irgendeinen messbaren Einfluss hat. wie üblich ungetestet.</p>
<pre><code class="language-cpp">~bstree()
{
    auto die = [](Node* p, Node* next) { delete p; return next; };
    Node* r=root;
    while(r){
        if(!r-&gt;left) {
_:          die( r, r-&gt;right );
            continue;
        }
        if(!r-&gt;right) {
            die( r, r-&gt;left );
            continue;
        }
        do {
            Node* e=r-&gt;left-&gt;right;
            Node* newR=r-&gt;left;
            newR-&gt;right=r;
            r-&gt;left=e;
            r=newR;
        } while ( r-&gt;left );
        goto _;
    }
}
</code></pre>
<p>Edit: nochmal überarbeitet. Jetzt ist der Anfangstest doch nicht nötig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2359370</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2359370</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 10 Oct 2013 10:01:28 GMT</pubDate></item></channel></rss>