使用 STL 反转递归链表

Reversing Linked List with Recursion, using STL

本文关键字:递归 链表 STL 使用      更新时间:2023-10-16

使用 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);
}

上面的代码生成 2 个错误。

错误 1(没有函数模板实例与参数列表匹配。(无错误号。

如果我删除第 1 行(在代码中提到(,那么上面的错误就不再存在。(为什么?

错误 2(C2783:"无效Reverse_list::反向1(无效(":无法推断"T"的模板参数

如何解决上述错误。

在上面的程序中,我想传递"头"节点(它是私有的(作为
参数到反向函数。但是我们不能访问类外的私人成员。所以我间接通过了。这是正确的通过方式吗?或者还有其他一些访问私人数据的方法?

我不确定你的意图,但是...

您正在尝试在另一个方法(Reverse()(中声明一个方法(reverse()(?嗯....

我们稍后再谈这个问题。

想象一下,以下指令是Reverse_list<T>::Reverse()的正确指令

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

为什么在back分配front->next(因此是特定Node<int>(时将声明为指向泛型Node<T>的指针?

如果将back定义为node<int>指针,则方法Reverse()不再有理由成为模板(依赖于T(方法。您可以避免这两个错误。

使用您的实际代码,当您调用时

rl.Reverse();

您调用模板方法,但编译器不知道如何确定T的类型。你可以用这种方式表达它

rl.Reverse<int>();

但是,如前所述,我认为最好删除整个模板部分。

或者,您也可以在模板类中转换整个类;其中head是指向泛型Node<T>的指针,而不是特定的Node<int>

类似的东西(如果我正确理解您的意图(

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); }

在这种情况下,在 main() 中,rl应声明为

Reverse_list<int> rl;

T修复为 int ,并且对Reverse()的调用应该是

rl.Reverse();

--- 编辑 2016.05.10 ---

使用"模板Reverse_list"解决方案,您应该(最后(纠正三点。

1(在类声明Reverse_list中,您在void Reverse()之前注释了template<typename T>行;好;您应该在void Display( list<T>& alist );之前删除(注释(同一行(出于同样的原因(;所以类变成了

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()现在是模板化类的方法;所以这条线

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

成为

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

3(现在reverse()是模板化类的方法;所以这条线

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

成为

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