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

时间:2016-04-18 21:42:16

标签: c++ class operator-overloading doubly-linked-list

我正在尝试阅读2个列表并将它们连接起来重载+运算符。我在课堂上很新,所以请耐心等待我,我想要的就是学习。我重载了流操作符,所以我可以读取和写入正常和反转的对象。我的+运算符会连接列表,但问题似乎是在main(list1 = list1 + list2;或者编写list3-连接list1和list2之后)。我几乎到处都在互联网上寻找答案,我结束了发布。如果你有任何链接或教程可以让我变得更快更容易,我会接受新的想法。非常感谢您阅读本文并尝试帮助^^

节点类:

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 << "\n\nNormal writing: ";
        nod *q = new nod;
        q = a.head;
        while (q != NULL)
        {
            output << q->data << " ";
            q = q->next;
        }
        q = a.tail;
        output << "\n\nReverse 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;
    }
};

主:

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

1 个答案:

答案 0 :(得分: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 << "\n\nNormal writing: ";
    nod *n = a.head;
    while (n)
    {
        output << n->data << " ";
        n = n->next;
    }

    n = a.tail;
    output << "\n\nReverse 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 << "\n\nNormal writing: ";
    for (std::list<int>::const_iterator iter = a.data.begin(), end = a.data.end(); iter != end; ++iter)
    {
        output << *iter << " ";
    }

    output << "\n\nReverse writing: ";
    for (std::list<int>::const_reverse_iterator iter = a.data.rbegin(), end = a.data.rend(); iter != end; ++iter)
    {
        output << *iter << " ";
    }

    return output;
}