【发布时间】:2021-09-05 14:35:23
【问题描述】:
我正在为双向链表实现插入(在元素之前)和添加(在元素之后)函数。我的问题是我必须返回的价值的差异以及它们为什么不同。
对于我的插入函数Link* insert(Link* n),我必须return n。对于我的添加函数Link* add(Link* n),我有return this。我已经测试了当我不这样做时会发生什么,之前/之后的元素不会出现。我想知道为什么会这样,为什么我不能return n(或return this)同时使用insert/add。
#include "std_lib_facilities.h"
class Link {
public:
string value;
Link(const string& v, Link* p = nullptr, Link* s = nullptr)
: value{v}, prev{p}, succ{s} { }
Link* insert(Link* n) ; // insert n before this object
Link* add(Link* n) ; // insert n after this object
Link* erase() ; // remove this object from list
Link* find(const string& s); // find s in list
const Link* find(const string& s) const; // find s in list
Link* advance(int n) const; // move n positions in list
Link* next() const { return succ; }
Link* previous() const { return prev; }
private:
Link* prev;
Link* succ;
};
//------------------------------------------------------------------------------
Link* Link::insert(Link* n) // insert n before this object; return n
{
if (n == nullptr) return this;
n->succ = this;
if (prev) prev->succ = n;
n->prev = prev;
prev = n;
return n; // why?
}
//------------------------------------------------------------------------------
Link* Link::add(Link* n) // insert n after this object
{
if (n == nullptr) return this;
n->prev = this;
if (succ) succ->prev = n;
n->succ = succ;
succ = n;
return this; // why?
}
//------------------------------------------------------------------------------
Link* Link::erase()
{
if (succ) succ->prev = prev; // if (succ != nullptr)
if (prev) prev->succ = succ;
return succ;
}
//------------------------------------------------------------------------------
Link* Link::find(const string& s) // find s in list;
// return 0 for "not found"
{
Link* p = this;
while(p) {
if (p->value == s) return p;
p = p->succ;
}
return 0;
}
//------------------------------------------------------------------------------
void print_all(Link* p)
{
cout << "{ ";
while (p) {
cout << p->value;
if ( (p = p->next()) ) cout << ", ";
}
cout << " }";
}
//------------------------------------------------------------------------------
int main()
{
Link* norse_gods = new Link{"Thor"};
norse_gods = norse_gods->insert(new Link{"Odin"});
norse_gods = norse_gods->insert(new Link{"Zeus"});
norse_gods = norse_gods->insert(new Link{"Freia"});
Link* greek_gods = new Link{"Hera"};
greek_gods = greek_gods->add(new Link{"Athena"});
greek_gods = greek_gods->add(new Link{"Mars"});
greek_gods = greek_gods->add(new Link{"Poseidon"});
Link* p = greek_gods->find("Mars");
if (p) p->value = "Ares";
// Move Zeus into his correct Pantheon:
{
Link* p = norse_gods->find("Zeus");
if (p) {
if (p==norse_gods) norse_gods = p->next();
p->erase();
greek_gods = greek_gods->insert(p);
}
}
// Finally, let's print out those lists:
print_all(norse_gods);
cout<<"\n";
print_all(greek_gods);
cout<<"\n";
}
//------------------------------------------------------------------------------
【问题讨论】:
-
您的
Link类同时充当列表本身和列表中的每个节点。您应该分离职责,即Link应该只是value的数据存储,然后创建一个管理Link实例列表的List类。您的所有列表操作(添加、插入、擦除、查找等)都应移至这个新的List类。然后add()和insert()可以返回新创建的Link节点。 -
@kino 向编写代码的人提出这个问题。:)
标签: c++ class linked-list dynamic-memory-allocation doubly-linked-list