重载+运算符以连接2个双列表

Overloading + operator to concatenate 2 doubly lists

本文关键字:2个 列表 连接 运算符 重载      更新时间:2023-10-16

我正在尝试读取两个列表,并将它们连接到重载+运算符。我刚开始上课,所以请耐心等待,我只想学习。我重载了流运算符,这样我就可以正常和反向地读写对象。My+运算符确实连接了列表,但问题似乎主要存在(list1=list1+list2;或者在连接list1和list2之后写入list3-)。我几乎在网上到处找答案,最后我发布了这个。如果你有任何链接或教程可以让我更快、更容易地成长,我会接受新的想法。感谢阅读本文并尝试帮助^^

节点类别:

class nod
{
public:
    int data;
    nod *next;
    nod *prev;
    friend class Lista;
    nod();
};

列表类

class Lista
{
private:
    nod *head;
    nod *tail;
    int size;
public:
    Lista();
    ~Lista();
    friend istream &operator >>(istream &input, Lista &a)
    {
        int i;
        cout << "Size of the list: ";
        input >> a.size;
        nod *q = new nod;
        q->prev = NULL;
        cout << "nFrist node: ";
        input >> q->data;
        a.head = q;
        a.tail = a.head;
        for (i = 1; i < a.size; i++)
        {
            nod *q = new nod;
            cout << "nNode number " << i + 1 << " is: ";
            input >> q->data;
            a.tail->next = q;
            q->prev = a.tail;
            a.tail = q;
            a.tail->next = NULL;
        }
        return input;
    }
    friend ostream& operator <<(ostream &output, Lista &a)
    {
        output << "nnNormal writing: ";
        nod *q = new nod;
        q = a.head;
        while (q != NULL)
        {
            output << q->data << " ";
            q = q->next;
        }
        q = a.tail;
        output << "nnReverse writing: ";
        while (q != NULL)
        {
            output << q->data << " ";
            q = q->prev;
        }
        return output;
    }
    Lista &operator+(Lista &rec)
    {
        Lista temp;
        temp.head = head;
        temp.tail = tail;
        temp.tail->next = rec.head;
        rec.head->prev = temp.tail;
        temp.tail = rec.tail;
        temp.size = size;
        temp.size = temp.size + rec.size;
        return temp;
    }
};

Main:

int main()
{
    Lista a,b,c;
    cin>>a;
    cin>>b;
    c=a+b;
    cout<<c;
    return 0;
}

您的operator+甚至还不是一个正确的实现。对于初学者来说,您返回的是对一个局部变量的引用,该变量在退出时超出了作用域,破坏了列表,并给调用者留下了对无效内存的悬空引用。但更糟糕的是,您将局部变量指向输入列表的节点,并操纵这些列表中的各种指针,破坏这两个列表。

operator+需要返回两个输入列表中数据的副本。这意味着为输出列表分配一组全新的节点。

试试类似的东西:

class nod
{
public:
    int data;
    nod *next;
    nod *prev;
    nod(int value = 0) :
        data(value), next(NULL), prev(NULL)
    {
    }
};

class Lista
{
private:
    nod *head;
    nod *tail;
    int size;
public:
    Lista() :
        head(NULL), tail(NULL), size(0)
    {
    }
    Lista(const Lista &src) :
        head(NULL), tail(NULL), size(0)
    {
        *this = src;
    }
    ~Lista()
    {
        Clear();
    }
    void Add(int value)
    {
        node *n = new nod(value);
        n->prev = tail;
        if (!head) head = n;
        if (tail) tail->next = n;
        tail = n;
        ++size;
    }
    void Clear()
    {
        nod *n = head;
        head = tail = NULL;
        size = 0;
        while (n)
        {
            nod *next = n->next;
            delete n;
            n = next;
        }
    }
    Lista& operator=(const Lista &rhs)
    {
        Clear();
        nod *n = rhs.head;
        while (n)
        {
            Add(n->data);
            n = n->next;
        }
        return *this;
    }
    Lista operator+(const Lista &rhs)
    {
        Lista temp;
        nod *n = head;
        while (n)
        {
            temp.Add(n->data);
            n = n->next;
        }
        n = rhs.head;
        while (n)
        {
            temp.Add(n->data);
            n = n->next;
        }
        return temp;
    }
    friend std::istream& operator >>(std::istream &input, Lista &a);
    friend std::ostream& operator <<(std::ostream &output, const Lista &a);
};
std::istream& operator >>(std::istream &input, Lista &a)
{
    // NOTE: this kind of code really does not
    // belong in an 'operator>>' implementation!
    int i, size, data;
    std::cout << "Size of the list: ";
    input >> size;
    for (i = 0; i < size; ++i)
    {
        std::cout << "nNode number " << i + 1 << ": ";
        input >> data;
        a.Add(data);
    }
    return input;
}
std::ostream& operator <<(std::ostream &output, const Lista &a)
{
    output << "nnNormal writing: ";
    nod *n = a.head;
    while (n)
    {
        output << n->data << " ";
        n = n->next;
    }
    n = a.tail;
    output << "nnReverse writing: ";
    while (n)
    {
        output << n->data << " ";
        n = n->prev;
    }
    return output;
}

int main()
{
    Lista a, b, c;
    std::cin >> a;
    std::cin >> b;
    c = a + b;
    std::cout << c;
    return 0;
}

现在,话虽如此,您应该认真摆脱手动链表实现,转而使用STL std::list类,该类管理节点的链表,并知道如何复制自己:

#include <list>
#include <algorithm>
#include <iterator>
class Lista
{
private:
    std::list<int> data;
public:
    void Add(int value)
    {
        data.push_back(value);
    }
    void Clear()
    {
        data.clear();
    }
    Lista operator+(const Lista &rhs)
    {
        Lista temp;
        std::copy(data.begin(), data.end(), std::back_inserter(temp));
        std::copy(rhs.data.begin(), rhs.data.end(), std::back_inserter(temp));
        return temp;
    }
    friend std::istream& operator >>(std::istream &input, Lista &a);
    friend std::ostream& operator <<(std::ostream &output, const Lista &a);
};
std::istream& operator >>(std::istream &input, Lista &a);
{
    // NOTE: this kind of code really does not
    // belong in an 'operator>>' implementation!
    int i, size, data;
    std::cout << "Size of the list: ";
    input >> size;
    for (i = 0; i < size; ++i)
    {
        std::cout << "nNode number " << i + 1 << ": ";
        input >> data;
        a.Add(data);
    }
    return input;
}
std::ostream& operator <<(std::ostream &output, const Lista &a)
{
    output << "nnNormal writing: ";
    for (std::list<int>::const_iterator iter = a.data.begin(), end = a.data.end(); iter != end; ++iter)
    {
        output << *iter << " ";
    }
    output << "nnReverse writing: ";
    for (std::list<int>::const_reverse_iterator iter = a.data.rbegin(), end = a.data.rend(); iter != end; ++iter)
    {
        output << *iter << " ";
    }
    return output;
}