Element aus Liste löschen



  • möchte beliebiges element aus einfach verketteter liste löschen.

    meine methode sieht so aus:

    void loeschen( int zahl)
    {	
    	if (anker == nullptr)
    		cout << "Die Liste ist leer!" << endl;
    	else
    	{
    		Liste *ptr = anker;
    
    		while (ptr->next != nullptr) //bis das ende der Liste erreicht ist... 
    		{
    			if (ptr->next->data == zahl)
    				break;
    			ptr = ptr->next; //es soll durch die Liste gelaufen werden 
    		}
    
    		if (ptr->next == nullptr && ptr->data != zahl)
    			cout << "Element ist nicht in Liste vorhanden!" << endl;
    		else {
    			delete ptr->next; 
    			ptr->next = ptr->next->next;
    
    	}
    }
    

    Es wird wenn ich die Liste ausgeben will angezeigt dass es eine zugriffsverletzung gibt.
    ich vermute, dass das element zwar gelöscht wurde, aber die liste nicht mehr richtig verkettet ist (?!).
    bitte lösung-/hilfvorschläge für die ahnungslosesten der ahnungslosen formulieren.
    DANKE



  • Du greifst nach dem Löschen auf das Element zu.

    Ein etwas subtilerer Bug: Kannst du das erste Element deiner Liste löschen (wenn die Liste mehr als ein Element hat)?



  • if (ptr->next == nullptr && ptr->data != zahl)
        cout << "Element ist nicht in Liste vorhanden!" << endl;
    else {
        delete ptr->next; 
        ptr->next = ptr->next->next; // ptr->next ist bereits freigegeben -> böse Leichenschändung
    }
    


  • ah okay!
    und wie kann ich es richtig löschen?

    beide zeilen vertauschen wahrscheinlich ja nicht?! 😕



  • Dangling schrieb:

    ah okay!
    und wie kann ich es richtig löschen?

    beide zeilen vertauschen wahrscheinlich ja nicht?! 😕

    Was könnte man wohl mit einer Kopie eines Pointers anfangen?



  • manni66 schrieb:

    Dangling schrieb:

    ah okay!
    und wie kann ich es richtig löschen?

    beide zeilen vertauschen wahrscheinlich ja nicht?! 😕

    Was könnte man wohl mit einer Kopie eines Pointers anfangen?

    weiß ich leider nicht 😕



  • hab es jetzt so angestellt

    void loeschen(int zahl)
    	{
    		if (anker == nullptr)
    			cout << "Die Liste ist leer!" << endl;
    		else
    		{
    			Liste *ptr = anker;
    			Liste *lptr ; //zulöschender pointer
    
    			if (ptr->data == zahl)
    			{
    				anker = ptr->next;
    				delete ptr;
    
    			}
    
    			else{
    
    				while (ptr->next != nullptr) //bis das ende der Liste erreicht ist... 
    				{
    					if (ptr->next->data == zahl)
    						break;
    					ptr = ptr->next; //es soll durch die Liste gelaufen werden 
    				}
    
    				if (ptr->next == nullptr && ptr->data != zahl)
    					cout << "Element ist nicht in Liste vorhanden!" << endl;
    				else
    				{
    					lptr = ptr->next;
    					ptr->next = ptr->next->next;
    					delete lptr;
    				}
    			}
    		}
    	}
    

    Elemente lassen sich löschen 🙂



  • Dangling schrieb:

    Elemente lassen sich löschen 🙂

    Auch das letzte?



  • MFK schrieb:

    Dangling schrieb:

    Elemente lassen sich löschen 🙂

    Auch das letzte?

    als ichs grad probiert hab schon!



  • kann mir jemand bei nem ähnlichen Problem helfen?
    möchte kleinstes element in liste löschen!

    sieht immoment so aus:

    void kleinstes_loeschen()
    	{
    		if (anker == nullptr)
    			cout << "Die Liste ist leer!";
    		else
    		{
    			int k = anker->data; //annahme: anker kleinstes element
    			Liste *ptr = anker; //Zeiger um Liste zu durchlaufen
    			Liste *ptr2; //Zeiger auf kleinstes Element 
    
    			if (anker->next == nullptr) //nur 1 Element in Liste
    			{
    				ptr2 = ptr;
    				anker = ptr->next;
    				delete ptr2; ptr=nullptr;
    			}
    			else
    			{
    				ptr2 = ptr;
    
    				Liste *ptr = anker;
    
    				while (ptr->next != nullptr)
    				{
    					if (ptr->next->data < k)
    					{
    						k = ptr->next->data;
    						ptr2 = ptr->next;
    					}
    					ptr = ptr->next;
    				}
    
    				if (k == anker->data)
    				{
    					anker = ptr->next;
    					delete ptr; delete ptr2;
    				}
    				else
    				{   ptr->next = ptr->next->next;
    					delete ptr2; 
    				}
    			}
    		}
    	}
    

  • Mod

    In Zeile 36 löscht du 2 Knoten. Das erscheint unplausibel.
    Eine Funktion sollte nach Möglichkeit nur eine Aufgabe erfüllen, das vereinfacht diese und macht es einfacher, die Korrektheit zu überprüfen. Das Finden des kleinsten Elementes und das Löschen eines Elementes sind hinreichend verschieden, dass es zweckmäßig erscheint, hierfür verschiedene Funktionen zu verwenden.
    z.B.

    void loesche_element(Liste*& element)
    // Trick: wir betrachten nicht den Knoten selbst, sondern den Zeiger, der den Knoten besitzt
    // damit verschwindet der Spezialfall des ersten Knotens
    {
        if ( Liste* p = element )
        {
            element = element->next;
            delete p;
        }
    }
    
    Liste*& finde_kleinstes_element(Liste*& anker)
    {
        Liste** p = &anker;
        for ( Liste** q = p; *q != nullptr; q = q->next )
            if ( (*q)->data < (*p)->data ) // der erste Vergleich ist eigentlich überflüssig, allerdings müsste man
                                           // andernfalls Spezialfälle behandeln
                p = q;
        return *p;
    }
    
    void loesche_kleinstes_element(Liste*& anker)
    {
        loesche_element( finde_kleinstes_element( anker ) );
    }
    

Log in to reply