我正致力于创建双向链表。我似乎遇到了pushBack
函数的问题(应该将一个节点添加到列表的末尾)。不知何故,它只是替换了第一个节点,并将其指向上一个节点和下一个节点。当我去打印列表时,它会永远继续下去,因为下一个节点不是NULL(因为正如我所说,它出于某种原因指向自己)。以下是整个计划。我想我的范围可能有问题,或者我可能错误地使用指针。
#include <iostream>
class Node {
public:
Node();
Node(int *val, Node *nx = NULL, Node *prev = NULL) {
value = val; next = nx; previous = prev;
}
void setPrev(Node* prev) { previous = prev; }
void setNext(Node* nx) { next = nx; }
void setVal(int* x) { value = x; }
Node* getPrev() { return previous; }
Node* getNext() { return next; }
int* getVal() { return value; }
private:
int* value;
Node *next;
Node *previous;
};
class LinkedList {
public:
LinkedList() : front(NULL), back(NULL) {}
bool empty() { return front == NULL; }
void pushBack(Node *nd) {
if (back == NULL) {
front = nd;
back = nd;
}
else {
back->setNext(nd);
nd->setPrev(back);
back = nd;
}
std::cout << "Front: " << *front->getVal() << std::endl;
std::cout << "Back: " << *back->getVal() << std::endl;
}
Node* topFront() { return front; }
void printFront() {
int *x = front->getVal();
std::cout << *x << std::endl;
}
void print() {
if (empty()) {
std::cout << "List is empty" << std::endl;
}
else {
std::cout << "Print list" << std::endl;
Node *x = front;
int count = 1;
// First just print the first element, then the rest
int *y = front->getVal();
std::cout << count << ": ";
std::cout << *y << std::endl;
x = x->getNext();
while (x != NULL) {
std::cout << count << ": ";
int *z = x->getVal(); std::cout << *z << std::endl;
x = x->getNext();
}
}
}
private:
Node* front;
Node* back;
};
int main() {
LinkedList ll;
char input;
char const *menu = {"Options:\n\n" \
"0. Quit\n" \
"1. Print linked-list\n" \
"2. pushBack -- add to the end of the LinkedList\n"};
while (input != '0') {
std::cout << menu << std::endl;
std::cout << ":";
std::cin >> input;
if (input == '1') {
ll.print();
}
else if (input == '2') {
std::cout << "Value: ";
static int init;
std::cin >> init;
static Node x(&init);
ll.pushBack(&x);
}
}
return 0;
}
以下是我使用的输入。我打印了一些值来尝试调试程序。您会注意到,我只是尝试将值为1,2,3和4的节点放入列表中
Options:
0. Quit
1. Print linked-list
2. pushBack -- add to the end of the LinkedList
:2
Value: 1
Front: 1
Back: 1
Node Prev: 0
Node Next: 0
Options:
0. Quit
1. Print linked-list
2. pushBack -- add to the end of the LinkedList
:2
Value: 2
Front: 2
Back: 2
Node Prev: 0x602300
Node Next: 0x602300
Options:
0. Quit
1. Print linked-list
2. pushBack -- add to the end of the LinkedList
:2
Value: 3
Front: 3
Back: 3
Node Prev: 0x602300
Node Next: 0x602300
Options:
0. Quit
1. Print linked-list
2. pushBack -- add to the end of the LinkedList
:2
Value: 4
Front: 4
Back: 4
Node Prev: 0x602300
Node Next: 0x602300
Options:
0. Quit
1. Print linked-list
2. pushBack -- add to the end of the LinkedList
:0
答案 0 :(得分:2)
这里有很多好的提示,但到目前为止都没有解决根本问题:你需要在堆上而不是堆栈上分配Node实例。
为了使这更容易,我建议你按值而不是指针存储int。将所有使用int *的地方改为普通的'int'。
然后更改代码以将背面的节点推送到此:
else if (input == '2') {
std::cout << "Value: ";
int init;
std::cin >> init;
Node *x = new Node(init);
ll.pushBack(x);
}
我已经用你的代码对它进行了测试,它对我有用。
当你做这样的事情时:
else if (input == '2') {
std::cout << "Value: ";
int init;
std::cin >> init;
Node x(init);
ll.pushBack(&x);
}
您正在堆栈上分配一个节点,这意味着只要退出“else”块,节点“x”就会被销毁,而添加到列表中的指针将不再有效。您需要使用new运算符在堆上分配Node。这将使Node保持活动状态,直到你以后删除它为止。
说到删除 - 一旦你使这个部分工作,你就会想要编写一个遍历列表中所有节点的析构函数并删除它们。但是现在,我专注于让你的其他操作正确。
答案 1 :(得分:-1)
当您在下面的代码中使用静态变量时,您的所有节点都将具有您输入的第一个值。
static int init;
std::cin >> init;
static Node x(&init);
如下所示进行纠正,然后重试
int *init = new int;
std::cin >> *init;
Node *x = New Node(init);
你的pushBack方法对我来说很好看。只需进行上述更改即可。