列表实现不能正确地汇总列表

时间:2017-07-05 08:46:26

标签: c++ data-structures

我正在尝试深入研究C ++中的数据结构。因此我正在学习如何写清单。一切似乎工作得很好,直到重载sum运算符+。对于两个给定的列表,它将列表中两个最高值相加。

这是.h文件:

typedef struct rob{
    int value;
    struct rob* next;
}element;

class list{
public:
    friend list& operator+(list&,list&);
    friend void merge(list& x,list& y);

    void show();
    bool search(int x);
    void append(int x);
    bool sortAppend(int x);
    list& operator--(int);

    bool empty() { return (inf.head==nullptr);}
    void clear() { inf.head = nullptr; }
    list() { inf.head = inf.tail = nullptr; }
    ~list() { while(!empty()) { (*this)--;}}

private:
    typedef struct{
        element* head;
        element* tail;
    }info;

    info inf;
};

我知道在 .h 文件中, typedef 可能看起来有点类C,但是标题设计是从我正在学习的书中复制的。我试图通过自己的作者想法来破解这些方法。

相关的功能定义:

#include "list.h"
bool list::sortAppend(int x){

element* newElem = new element;
newElem->value = x;
if (empty()){
    inf.head=inf.tail=newElem;
    newElem->next=nullptr;
    return true;
}
else if ( (newElem->value) < (inf.head->value) ){ 
    newElem->next=inf.head;
    inf.head=newElem;
    return true;
}
else if ( (newElem->value) > (inf.tail->value) ) {
    newElem->next=nullptr;
    inf.tail->next=newElem;
    return true;
}
element* tempHead = inf.head;
while(tempHead!=inf.tail){

    if ( (newElem->value) < (tempHead->next)->value) {
           newElem->next = (tempHead->next);
           tempHead->next = newElem;
           return true;
    }
    else{
    tempHead = tempHead->next;
    }   
}
return false;
}

list& operator+(list& X, list& Y){
    list* tempListArr[2] = {&X, &Y};
    list* tempList = new list;
    for(const list* i: tempListArr)
    {
        element* tempHead = (i->inf).head;
        while(tempHead!= nullptr){
            tempList->sortAppend(tempHead->value);
            tempHead = tempHead->next;
            }   
            tempList->show();
            std::cout << "--\n";
    }
    return *tempList;
}

对于包含值的给定列表:

#include <iostream>
#include "list.cpp"

int main(){

    list myList;
    myList.sortAppend(5);
    myList.sortAppend(2);
    myList.sortAppend(4);
    list myList2;
    myList2.sortAppend(21);
    list myList3;

    myList3 = myList + myList2;

    return 0;

}

有人能指出我犯了哪个错误吗?我现在被困了几个小时,我不知道出了什么问题。

非常感谢提前!

关注:

sortAppend方法肯定有效。它确实根据需要创建排序列表。 +运算符定义本身一定有问题虽然我已经尝试过,而不是范围循环,使用for循环进行一次迭代,但我仍然只得到两个值的列表。

2 个答案:

答案 0 :(得分:1)

您根本没有将inf.tail设置为

中的新尾部
else if ((newElem->value) > (inf.tail->value)) {
    newElem->next = nullptr;
    inf.tail->next = newElem;
    inf.tail = newElem; // <-- missing!
    return true;
}

您应该 - 至少 - 更改operator +的签名以返回list而不是列表引用,并返回本地对象而不是无主堆对象(这是内存泄漏)。如果这样做,您还必须编写复制构造函数和复制赋值运算符。

答案 1 :(得分:1)

鉴于您的代码,

list myListWierd;
myListWierd.sortAppend(2);
myListWierd.sortAppend(4);
myListWierd.sortAppend(5);
myListWierd.show();

显示

2
5

因此sortAppend不起作用。

麻烦在于更新尾部,因为operator +依赖于使用尾部。

我可以为您排序代码并使其正常工作;确实安德烈亚斯的答案就是这样。但是现在,请注意你已经假设一个函数有效,但是我发现了一个案例,通过查看移动部件 - 我们创建的列表,然后我们尝试以不同的顺序重新创建它不起作用。作为一般规则,尝试一个错误的函数中的所有部分,一次一个,也许作为单元测试。

现在,让我们提出一些建议,而不是解决这个问题。

首先,析构函数除了行走指针之外什么都不做(使用empty使用head而不是尾部 - 所以head需要设置如前所述

~list() { while (!empty()) { (*this)--; } }

如果你不想要泄密,你需要多考虑一下。

接下来,

list& operator+(list&, list&)

创建一个指针并返回其内容。这是一个坏主意。永远不要这样做。

现在,将签名更改为

list operator+(list&, list&);

然后返回一个列表:

list operator+(list& X, list& Y) {
    list* tempListArr[2] = { &X, &Y };
    list tempList;//copy it over to the calling vode otherwise DANGER
    for (const list* i : tempListArr)
    {
        element* tempHead = (i->inf).head;
        while (tempHead != nullptr) {
            tempList.sortAppend(tempHead->value);
            std::cout << "Adding " << tempHead->value << '\n';
            tempHead = tempHead->next;
        }
        tempList.show();
        std::cout << "--\n";
    }
    return tempList;
}