我尝试在各个阶段使用cout来计算,但徒劳无功。在刷新反向列表中的前两个值后,程序崩溃。它打印一个垃圾值作为第三个值,在它打印最后两个值之前,它会崩溃。
#include <iostream>
using namespace std;
class LLStack {
public:
struct Node {
int data;
Node* next;
Node(int n) {
data = n;
next = 0;
}
Node(int n, Node* node) {
data = n;
next = node;
}
};
LLStack();
LLStack(const LLStack&);
LLStack& operator = (const LLStack&);
~LLStack();
void push(int);
int pop();
int top();
bool isEmpty();
void flush();
private:
Node* head;
};
LLStack::LLStack() {
head = 0;
}
LLStack::LLStack(const LLStack& s) {
head = new Node(NULL);
head->data = s.head->data;
if (s.head->next != NULL) {
head->next = new Node(*(s.head->next));
}
else {
head->next = new Node(NULL);
}
}
LLStack::~LLStack() {
this->flush();
}
LLStack& LLStack::operator = (const LLStack& s) {
this->head = new Node(NULL);
this->head->data = s.head->data;
if (s.head->next != NULL) {
this->head->next = new Node(*(s.head->next));
}
else {
this->head->next = new Node(NULL);
}
return *this;
}
void LLStack::push(int x) {
if (head == 0) head = new Node(x);
else {
Node* temp = new Node(x, head);
head = temp;
}
}
int LLStack::pop() {
if (head == 0) {
cout << "\n\nNo elements to pop\n\n";
return -1;
}
else {
Node* temp = head;
int n = temp->data;
head = temp->next;
delete temp;
return n;
}
}
int LLStack::top() {
if (head == 0) {
cout << "\n\nNo elements in the stack\n\n";
return -1;
}
else {
return head->data;
}
}
bool LLStack::isEmpty() {
return (head == 0);
}
void LLStack::flush() {
if (head == 0) {
cout << "\n\nNo elements in the Stack to flush\n\n";
return;
}
cout << "\n\nFlushing the Stack: ";
Node* temp = 0;
while (head != 0) {
temp = head;
cout << temp->data << " ";
head = head->next;
delete temp;
}
cout << endl << endl;
}
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1 = s2;
}
int main() {
LLStack s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
s.push(5);
reverseStack(s);
cout << "\n\nFlushing s:\n";
s.flush();
return 0;
}
请运行它,你会明白的。因此,我非常沮丧。请帮忙。
答案 0 :(得分:2)
您的复制构造函数和赋值运算符对我来说看起来不正确。它们仅复制两个节点head
和head->next
。堆栈的其余部分呢? next
的副本仍将指向之前指向的内容。如果原始文件被删除,例如s2
超出reverseStack
末尾的范围,则会指向已删除的Node
。
您还需要考虑如何处理赋值运算符中堆栈的现有状态。
我能看到修复代码的最简单方法是根本不使用复制构造函数或赋值运算符。我会明确地删除它们,直到你让它们工作:
LLStack(const LLStack&) = delete;
LLStack& operator=(const LLStack&) = delete;
但是你的堆栈很容易write a swap
function:
void LLStack::swap(LLStack& rhs) {
std::swap(head, rhs.head);
}
然后您可以在reverseStack
中使用它而不是赋值运算符:
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1.swap(s2);
}
答案 1 :(得分:-2)
从delete temp;
void LLStack::flush() {}
void LLStack::flush() {
if (head == 0) {
cout << "\n\nNo elements in the Stack to flush\n\n";
return;
}
cout << "\n\nFlushing the Stack: ";
Node* temp = 0;
while (head != 0) {
temp = head;
cout << temp->data << " ";
head = head->next;
// delete temp; //delete
}
cout << endl << endl;
}