Elemente verkehrt auf Queue geschoben
-
Hi ich hab ein Programm geschrieben wo Int-Werte aus einer Datei auf ein Queue geschoben werden und danach per Bucketsort wieder sortiert in eine neue Datei ausgibt.Aber mein Programm schiebt die Elemente Verkehrt auf den Queue.
#include <iostream> #include <fstream> using namespace std; #ifndef _QUEUE_H #define _QUEUE_H template <class T> class Queue { public: Queue(): counter(0), topp (0){} //Konstruktor ~Queue(){} //Destruktor //Funktionsprototypen void deque(); //löschen des ersten Elements bool enque(const T&); //einfügen eines Elements ans Ende T& first()const; //Zugriff auf das erste Element bool isEmpty()const; //Test ob Queue leer ist private: class qNode { public: T data; qNode *next_element; }; qNode *topp; //Zeiger auf erstes Element int counter; //zählt wie viel elemente in Queue }; //Funktionen //prüft ob Queue leer ist, 0 Queue ist nicht leer und 1 Queue ist leer template <class T> bool Queue<T>::isEmpty()const { if(counter == 0) return true; else return false; } //fügt Element am Ende an template <class T> bool Queue<T>::enque(const T& einzufuegendes_element) { qNode *node = new qNode; node->data = einzufuegendes_element; node->next_element = topp; topp = node; ++counter; return true; } //löscht erstes element template <class T> void Queue<T>::deque() { qNode *old_element = topp; topp = topp->next_element; delete old_element; --counter; } //gibt erstes element zurück template <class T> T& Queue<T>::first()const { return topp->data; } #endif int main(int argc, char *argv[]) { char *input; char *output; char in[10]="input.txt"; char out[11]="output.txt"; if(argc >= 3) { input = argv[1]; output = argv[2]; } else { input = in; output = out; } fstream quelle; quelle.open(input, ios::in); fstream ziel(output, ios::out); Queue<int> intQueue; cout << "Queue leer? 0->nein....1->ja " << intQueue.isEmpty() << endl; //Werte aus Datei auf Queue schieben int value; while(quelle >> value) { intQueue.enque(value); cout << value << " " << "abgelegt !" << endl; } cout << "Queue leer? 0->nein....1->ja " << intQueue.isEmpty() << endl; cout << intQueue.first(); //bucketsort //geöffnete Datein schließen quelle.close(); ziel.close(); }Gruß
-
Ähm, was ist mit deinem anderen Thread?
http://www.c-plusplus.net/forum/viewtopic-var-t-is-243507.htmlAbgesehen davon findest du sowas sehr schnell raus, indem du dir auf Blatt Papier kurz überlegst, wie deine Queue technisch ablaufen sollte, und dann über den Debugger mit deinem Programm vergleichst.
-
Schon ok, war en irrtum. Ist schon alles gelöst....

-
WINFO2105 schrieb:
#include <iostream> #include <fstream> using namespace std; //! Nicht in Headern! #ifndef _QUEUE_H //_X (Unterstrich, Großbuchstabe)-Bezeichner sind für Compiler reserviert - also nimm mal den Unterstrich am Anfang weg und benenn das makro mal iwie so, dass es definitiv niemand anders schon zufällig nutzt... #define _QUEUE_H template <class T> class Queue { public: Queue(): counter(0), topp (0){} //Konstruktor // ~Queue(){} //Destruktor //einen leeren destruktor musst du auch nicht zu deklarieren+definieren - da reicht der compilergenerierte //Funktionsprototypen void deque(); //löschen des ersten Elements bool enque(const T&); //einfügen eines Elements ans Ende // T& first()const; //Zugriff auf das erste Element //eine non-const referenz auf das erste element -> möglichkeit, daten zu ändern -> non-const memberfkt! also brauchen wir 2 fkt., wenn wir auch eine non-const reference wiedergeben wollen: const T& first()const; //Zugriff auf das erste Element T& first(); //Zugriff auf das erste Element bool isEmpty() const; //Test ob Queue leer ist private: class qNode { public: T data; qNode *next_element; //ein konstruktor ist nie falsch: qNode(const T& value, qNode *_next_element) : data(value), next_element(_next_element) //initialisierungsliste {} }; qNode *topp; //Zeiger auf erstes Element int counter; //zählt wie viel elemente in Queue //den counter brauchst du eigtl nicht: size_t size() const { size_t R(0); for(qNode* i=topp; topp; topp = topp->next_element, ++R); return R; } }; //Funktionen //prüft ob Queue leer ist, 0 Queue ist nicht leer und 1 Queue ist leer template <class T> bool Queue<T>::isEmpty()const { return counter == 0; //bzw. return !counter; //oder ohne counter: return topp == 0; //also return !topp; } //fügt Element am Ende an template <class T> //bool - wieso bool, wenn du so und so immer true zurückgibst? void Queue<T>::enque(const T& einzufuegendes_element) { // qNode *node = new qNode; // node->data = einzufuegendes_element; // node->next_element = topp; // topp = node; //zwischenschritt, da wir jetzt einen konstruktor haben: // qNode *node = new qNode(einzufuegendes_element, topp); // topp = node; //wird zu: topp = new qNode(einzufuegendes_element, topp); //und das hier bleibt, falls du weiter mit dem counter arbeiten möchtest: ++counter; } //löscht erstes element template <class T> void Queue<T>::deque() { qNode *old_element = topp; topp = topp->next_element; delete old_element; --counter; } //gibt erstes element zurück template <class T> const T& Queue<T>::first() const { return topp->data; } //gibt veränderbares erstes element zurück template <class T> T& Queue<T>::first() { return topp->data; } #endif #include <string> int main(int argc, char *argv[]) { // char *input; // char *output; const char in[]="input.txt"; //! const char out[]="output.txt"; //! if(argc >= 3) { input = argv[1]; output = argv[2]; } else { input = in; output = out; } fstream quelle; quelle.open(input, ios::in); fstream ziel(output, ios::out); Queue<int> intQueue; //sieht so schöner aus, meinst du nicht auch?! cout << "Die Queue ist "; if (intQueue.isEmpty()) cout << "nicht "; cout << "leer?" << endl; //Werte aus Datei auf Queue schieben int value; while(quelle >> value) { intQueue.enque(value); cout << value << " " << "abgelegt !" << endl; } //und so geht es kürzer: cout << "Die Queue ist " << (intQueue.isEmpty() ? "nicht "); cout << "leer?" << endl; if(! intQueue.isEmpty()) //wichtig! ansonsten bekommst du hier müll! cout << intQueue.first(); /*...*/ //brauchst du nicht, weil die klassen das im destruktor automatisch machen: //geöffnete Datein schließen // quelle.close(); // ziel.close(); }ich hoffe, es hilft dir...
da es mir noch einfällt:
du brauchst nen destruktor - allerdings musst du dort auch den speicherplatz freigeben - das macht man in der regel so:template <typename T> void clear() //zusätzliche öffentliche member-fkt, da man diese funktionalität ja auch nach außen anbieten kann { while(! isEmpty()) deque(); } template <typename T> Queue::~Queue() //unser destruktor ruft jz einfach clear auf... { clear(); }bb
gibt nat. noch ca. 100 andere kleine dinge, die man verbessern könnte - aber das sollte für den anfang erst mal genügen...
-
Ich würde zum Beispiel andere Bezeichner verwenden.
dequeist schon mal sehr irreführend, da es in der Standardbibliothek einen Container mit diesem Namen gibt. Das steht dort für Double Ended Queue. Undenqueist nicht viel besser.Halte dich doch ein wenig an inoffizielle Konventionen und nenne die Methoden
pushundpop, dann weiss jeder, was gemeint ist. Oder hänge bei deinen Namen mindestens noch einuean, damit diese auch Wörter sind.