我正在尝试深入研究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循环进行一次迭代,但我仍然只得到两个值的列表。
答案 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;
}