我正在用c ++实现一个简单的链表。 我有一个错误,我没有看到它:(
#include <stdexcept>
#include <iostream>
struct Node {
Node(Node *next, int value):
next(next), value(value) {
}
Node *next;
int value;
};
class List {
Node *first;
int len;
Node *nthNode(int index);
public:
List():first(0),len(0){
}
// Copy - Konstruktor
List(const List & other){
};
// Zuweisungs - Operator O(len +other.len)
List &operator=(const List &other) {
clear();
if(!other.len) return *this;
Node *it = first = new Node(0,other.first->value);
for (Node *n = other.first->next; n; n = n->next) {
it = it->next = new Node(0, n->value);
}
len = other.len;
return *this;
}
// Destruktor
~List(){
};
void push_back(int value){
};
void push_front(int value){
Node* front = new Node(0,value);
if(first){
first = front;
front->next = 0;
}else{
front->next = first;
first = front;
}
len++;
};
int &at(int index){
int count = 0 ;
int ret ;
Node *it = first;
for (Node *n = first->next; n; n = n->next) {
if(count==index) ret = n->value;
count++;
}
return ret ;
};
void clear(){
};
void show() {
std::cout << " List [" << len << " ]:{ ";
for (int i = 0; i < len; ++i) {
std::cout << at(i) << (i == len - 1 ? '}' : ',');
}
std::cout << std::endl;
}
};
/*
*
*/
int main() {
List l;
// l. push_back(1);
// l. push_back(2);
l. push_front(7);
l. push_front(8);
l. push_front(9);
l.show();
// List(l). show();
}
它有效...但输出是:
列表[3]:{0,134520896,9484585}
答案 0 :(得分:3)
push_front
逻辑错误。它应该是这样的:
void push_front(int value){
first = new Node(first, value);
++len;
}
虽然我们处于此状态,但您的operator=
并非例外。在copy-constructor中实现复制并使用copy-and-swap惯用语分配:
List& operator=(List other) { swap(other); return *this; }
void swap(List& other) {
Node* tnode = first; first = other.first; other.first = tnode;
int tlen = len; len = other.len; other.len = tlen;
}
另一方面,请勿实现at
成员函数;随机访问是非常低效的,不应该鼓励。改为实现迭代器。
答案 1 :(得分:2)
您将在at
中返回对局部变量的引用。当函数退出时,变量超出范围。之后访问它是未定义的行为。你很幸运它没有崩溃。
您还应该重新考虑show(O(n * n)认真?)和push_front(if(first)?)的实现。
以下是更好的实现:
Node *at(int index){
int count = 0 ;
for (Node *n = first; n; n = n->next) {
if(count==index)
return n;
count++;
}
return NULL;
};
它不会返回引用。如果index大于列表的长度,则不能返回NULL引用。 我还将返回类型更改为Node,因此调用者可以更改值。