Warteschlange richtig ?



  • Hallo an Alle, liebe Grüsse,

    Ich bin neu hier und habe auch direkt eine Frage:
    Ich habe mir eine Warteschlange programmiert, also das Hinzufügen und das Herausnehmen. Nunja wir sollen nur ein Pointer als "orientierung" haben, das heisst zBsp ein Pointer der den Anfang der Liste kennzeichent. Denn eigentlich kann man den Push() eines Stacks und die Queue() einer Warteschlange gleich schreiben, man muss nur nachher beim herausnehmen drauf achten ob das erste oder das letzte element zu erst rausgenommen wird.

    Mein Hinzufügen, also Queue sieht so aus:

    struct Paket{
      int Nummer;
      char name[20];
      Paket *next;
    }*anfang;
    
    struct Paket* Push(Paket*, int Nummer, char[] name){
      struct Paket *hilfptr; //Hilfspointer
      hilfsptr=new TS;
    
      if(anfang==NULL){
        hilfsptr->next=NULL;
      }
      else {
        hilfsptr->next=anfang;
      }
    
      anfang=ptr;
      anfang->Nummer=2;
      strcpy(anfang->name,"hallo");
    
      return anfang;
    
    };
    

    Mein Hinzufügen ist halt so programmiert dass der Zeiger "anfang" immer mit durch die Liste wandert, zeigt also immer auf das neueste Element.

    Und das herausnehmen:

    struct Paket* Pop(Paket *){
      struct Paket *hilfsptr;
      ptr=anfang;
      if(ptr==NULL) || (ptr->next==NULL){
        return -1;
      }
    
      while(ptr->next->next !=NULL){
        ptr=ptr->next;
      }
    
      free(ptr->next);
      ptr->next=Null;
    
      return // wie soll ich das gelöschte paket zurückgeben zum auslesen ?
    };
    

    Also wollte fragen ob mein Code richtig ist. Habe ihn mehrmals getestet in dem ich mir die verkettete Liste aufgezeichnet habe und somit Zeile für Zeile durchgegangen bin

    Mit vielen Grüssen,
    -neuername



  • Ich hab mal versucht, in Deinem Stil einen Stack zu machen. Weil Pop irgendwie zwei Sachen zugleich zurückgeben müßte, hab ich den Aufruf so geändert, daß ein Zeiger auf Zeiger verwendet wird.

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    struct Paket {
    	int Nummer;
    	char name[20];
    	Paket* next;
    };
    
    struct Paket* Push(Paket** pStack, int Nummer, char name[]) {
    	struct Paket* hilfptr; //Hilfspointer
    	hilfptr=new Paket;
    
    	hilfptr->next=*pStack;
    	*pStack=hilfptr;
    	hilfptr->Nummer=Nummer;
    	strcpy(hilfptr->name,name);
    };
    
    struct Paket* Pop(Paket** pStack) {
    	struct Paket* hilfptr;
    	hilfptr=*pStack;
    	*pStack=(*pStack)->next;
    	return hilfptr;
    };
    
    int main() {
    	Paket* stack=0;
    	Push(&stack,1,"eins");
    	Push(&stack,2,"zwei");
    	Push(&stack,3,"drei");
    	Push(&stack,4,"vier");
    
    	while(stack!=0){
    		Paket* p=Pop(&stack);
    		cout<<p->Nummer<<' '<<p->name<<'\n';
    		delete p;
    	}
    }
    

    Wie man eine Queue machen würde, mag ich mir gerade nicht ausdenken.



  • Was meinst du damit? Ist mein Queue nicht gut bzw sauber programmiert ?

    Ist bei dir der pStack der anfangs Zeiger ?



  • neuername schrieb:

    Was meinst du damit? Ist mein Queue nicht gut bzw sauber programmiert ?

    In C++ ist es üblich, daß man die Funktionalität von Klassen in Methoden reinsteckt. Das ginge dann ungefähr so

    #include <iostream>
    #include <string>
    #include <cassert>
    using namespace std;
    
    struct Data{
    	int number;
    	string name;
    };
    
    class Stack{
    	struct Node{
    		Data data;
    		Node* next;
    	};
    	Node* anchor;
    	public:
    	Stack(){
    		anchor=0;
    	}
    	//Copy-Ctor und op= man weggelassen, ich Sünder
    	~Stack(){
    		while(!isEmpty())
    			pop();
    	}
    	bool isEmpty(){
    		return anchor==0;
    	}
    	void push(Data d){
    		Node* newNode=new Node;
    		newNode->data=d;
    		newNode->next=anchor;
    		anchor=newNode;
    	}
    	void pop(){
    		assert(!isEmpty());
    		Node* toDie=anchor;
    		anchor=anchor->next;
    		delete toDie;
    	}
    	Data peek(){
    		assert(!isEmpty());
    		return anchor->data;
    	}
    };
    
    int main() {
    	Stack s;
    	s.push(Data{1,"eins"});
    	s.push(Data{2,"zwei"});
    	s.push(Data{3,"drei"});
    	s.push(Data{4,"vier"});
    
    	while(!s.isEmpty()){
    		Data d=s.peek();
    		cout<<d.number<<' '<<d.name<<'\n';
    		s.pop();
    	}
    }
    

    neuername schrieb:

    Ist bei dir der pStack der anfangs Zeiger ?

    Ja. Nein. Es ist ein Zeiger auf den Anfangszeiger.



  • @neuername
    Ich vermute du wärst im C Unterforum besser aufgehoben, auch wenn du dein Programm mit einem C++ Compiler übersetzt.


  • Mod

    Ich vermute du wärst im C Unterforum besser aufgehoben, auch wenn du dein Programm mit einem C++ Compiler übersetzt.

    Bewirb' dich schnell als Moderator, dann kannst du den Thread noch morgen früh verschieben! 🤡

    @volkard: Was passiert eigentlich wenn man statt einem "rohen" Zeiger auf die nächste Node einen unique_ptr nimmt? Und dann nur den unique_ptr zerstört der die Root-Node besitzt?
    Edit: ... ein Haufen ineffizienter rekursiver Destruktor-Aufrufe?



  • Arcoth schrieb:

    @volkard: Was passiert eigentlich wenn man statt einem "rohen" Zeiger auf die nächste Node einen unique_ptr nimmt? Und dann nur den unique_ptr zerstört der die Root-Node besitzt?

    Geht alles klar. Würde ich aber nie machen.

    Bei der Liste hätte ich auch Angst um die Rekursionstiefe.



  • Arcoth schrieb:

    Bewirb' dich schnell als Moderator, dann kannst du den Thread noch morgen früh verschieben! 🤡

    😕


Anmelden zum Antworten