2016-05-09 7 views
0

-Code unter Verwendung für mit Rekursion verlinkte Liste Rückwärts fahren, mit STLReversierung mit Rekursion verlinkte Liste, STL

  #include<iostream> 
#include<conio.h> 
#include<list> 
using namespace std; 
template<typename T> 
class node 
{ 
public: 
    T data; 
    node<T> *next; 
    node(){ next = NULL; } 
    node(const T& item, node<T> *nextnode = NULL) 
    { 
     data = item; 
     next = nextnode; 
    } 
}; 
template<typename T> 
class Reverse_list 
{ 
private: 
    node<T> *head; 
    void reverse(node<T> *front); 
public: 
    Reverse_list(){ head = NULL; } 
    //template<typename T> 
    void Reverse(); 
    template<typename T> 
    void Display(list<T>& alist); 
}; 


int main() 
{ 
    Reverse_list <int> rl; 
    list<int> intlist; 
    int size, no; 
    cout << "Size of List ?? "; 
    cin >> size; 
    for (int i = 1; i <= size; i++) 
    { 
     cout << "Enter the " << i <<" "<< "element"; 
     cin >> no; 
     intlist.push_front(no); 
    } 


    rl.Display(intlist); 

    rl.Reverse(); 
    rl.Display(intlist); 
    _getch(); 
    return 0; 

} 

template<typename T> 
void Reverse_list<T>::Display(list<T>& alist) 
{ 
    list<int>::iterator iter = alist.begin(); 
    while (iter != alist.end()) 
    { 
     cout << *iter << " "; 
     iter++; 
    } 
} 

template<typename T> 
void Reverse_list<T>::reverse(node<T> *front) 
{ 
    if (front->next == NULL) 
    { 
     head = front; 
     return; 
    } 
    reverse(front->next); 
    node<int> *back = front->next; 
    back->next = front; 
    front->next = NULL; 
} 
template<typename T> 
void Reverse_list<T>::Reverse() 
{ 
    reverse(head); 
} 

Der obige Code erzeugt zwei Fehler.

Fehler 1) Keine Instanz der Funktionsvorlage entspricht der Argumentliste. (Keine Fehlernummer.)

Wenn ich Zeile 1 (erwähnt in einem Code) entferne, dann ist der obige Fehler nicht mehr. (Warum?)

Fehler 2) C2783: 'Leere Reverse_list :: Reverse1 (void)': konnte nicht Template-Argument für 'T'

ableiten Wie oben Fehler zu lösen.

Im obigen Programm, I wollte "head" node (die privat ist) passieren, wie
Argumentfunktion umkehrt. Aber wir können nicht auf private Mitglieder außerhalb der Klasse zugreifen. Also passierte ich indirekt. Ist das ein richtiger Weg? Oder gibt es eine andere Möglichkeit, auf private Daten zuzugreifen?

+0

Warum brauchen Sie eine Reverse-Funktion eine Vorlage zu sein? – teivaz

+1

Alles falsch mit 'intlist.reverse()'? – juanchopanza

+0

@ teivaz: Eigentlich möchte ich lernen, STL in C++. Also habe ich begonnen, mit einfacher Programmierung zu lernen. Aber befürchte, dass mein Professor wegen reiner STL denkt, dass ich Logik nicht kenne. Also Mittelweg ist, schreibe ein Programm mit STL und unserer Logik. Deshalb habe ich die verknüpfte Liste mit STL akzeptiert, aber mit der Logik umgekehrt. – Tushar

Antwort

0

Ich bin nicht sicher, Ihre Absichten zu verstehen, aber ...

Sie versuchen, eine Methode (reverse()) in einem anderen Verfahren (Reverse()) zu erklären? Uhmmm ....

Wir kommen später darauf zurück.

Stellen Sie sich vor, dass die folgende Anweisung richtige Anweisung von Reverse_list<T>::Reverse()

node<T> *back = front->next; 

ist, warum Sie back als Zeiger auf eine generische Node<T> erklären, wenn Sie front->next zuweisen (so eine bestimmte Node<int>), um es?

Wenn Sie back als node<int> Zeiger, wobei das Verfahren definieren Reverse() nicht mehr Grund hat eine Schablone (abhängig von T) Methode. Und Sie können beide Fehler vermeiden.

Mit Ihrem aktuellen Code, wenn Sie

rl.Reverse(); 

rufen rufen Sie eine Vorlage Methode, aber der Compiler nicht weiß, wie die Art T zu bestimmen. Sie könnten explizit auf diese Weise

rl.Reverse<int>(); 

aber, wie schon geschrieben, ich thik es besser ist, wenn Sie die ganze Vorlage Teil entfernen.

Oder alternativ können Sie die gesamte Klasse in eine Vorlagenklasse transformieren; wo head ist ein Zeiger auf eine generische Node<T>, keine specifica Node<int>.

So etwas (wenn ich das richtig, Ihre Absichten zu verstehen)

template <typename T> 
class Reverse_list 
{ 
    private: 
     node<T> *head; 

     void reverse (node<T> * front); 

    public: 
     Reverse_list() : head(NULL) 
     { } 

     void Reverse(); 
     void Display(list<T>& alist); 
}; 

template<typename T> 
void Reverse_list<T>::reverse (node<T> * front) 
{ 
    if (front->next == NULL) 
    { 
     head = front; 
     return; 
    } 
    reverse(front->next); 
    node<T> *back = front->next; 
    back->next = front; 
    front->next = NULL; 
} 

template<typename T> 
void Reverse_list<T>::Reverse() 
{ reverse(head); } 

In diesem Fall in main(), rl sollte als

Reverse_list<int> rl; 

Befestigungs T als int, und der Aufruf von Reverse() deklariert werden sollte

sein
rl.Reverse(); 

--- EDIT 2016.05.10 ---

Mit der "Template Reverse_list" Lösung, sollten Sie drei Punkte (zuletzt) ​​korrigieren.

1) in Reverse_list Klassendeklaration haben Sie die Zeile template<typename T> vor void Reverse() kommentiert; gut; Sie sollten die gleiche Zeile (aus dem gleichen Grund) löschen (kommentieren), bevor void Display(list<T>& alist);; so wird die Klasse

template<typename T> 
class Reverse_list 
{ 
private: 
    node<T> *head; 
    void reverse(node<T> *front); 
public: 
    Reverse_list(){ head = NULL; } 
    //template<typename T> 
    void Reverse(); 
    //template<typename T> 
    void Display(list<T>& alist); 
}; 

2) Display() nun ein Verfahren einer Templat-Klasse ist; so dass die Linie

list<int>::iterator iter = alist.begin(); 

werden

list<T>::iterator iter = alist.begin(); 

3) reverse() nun ein Verfahren einer Templat-Klasse ist; so dass die Linie

node<int> *back = front->next; 

werden

node<T> *back = front->next; 
+0

Sie haben meine Absicht richtig verstanden. Aber habe Zweifel. 1) In main(), warum rl als Reverse_list deklariert werden sollte rl ?? 2) Warum haben Sie void reverse (Knoten * Front) als privat gemacht? – Tushar

+0

(1) sollten Sie 'rl' als' Reverse_list '** deklarieren, ** wenn Sie' Reverse_list' in einer Template-Klasse für revers generische Liste transformieren; Es ist der einzige Modus (der einzige Modus, den ich kenne), dem Compiler die spezifische Klasse 'T' (' int', in Ihrem Fall; wenn Sie 'Reverse_list' als nicht-templatete Klasse beibehalten (nur in der Lage, Reverse-Listen von Integer) Du solltest 'rt' als einfache' Reverse_list' deklarieren, wie jetzt; – max66

+0

(2) Ich habe 'reverse()' als 'private' gemacht, weil es nur von einer anderen Methode der Klasse benutzt wird und ich nicht sehe irgendeinen Grund, es öffentlich zu machen; wenn du es direkt verwenden willst (wie 'Reverse()'), kannst du es als "public" deklarieren, aber ich schlage vor, eine Methode 'public' nur dann zu deklarieren, wenn ein Grund vorliegt in 'public'; deklariere es' private' (oder 'protected') sonst – max66