0

我正在尝试使用 C++ 中的链表创建一个堆栈。但是我写的显示函数只打印堆栈的顶部。我真的不明白为什么会这样。非常感谢任何帮助或澄清。谢谢

#include<iostream.h>
#include<conio.h>

class Node
{
protected:

    Node* next;
    int data;

public:

    Node(int d){data=d;}
    friend class Stack;
};

class Stack
{
public:
    Stack(){top->next='\0';length=0;}

void push(int d)
{
    Node *n=new Node(top->data);
    n->next='\0';
    top->next=n;
    top->data=d;
    length++;
}

int pop()
{
    top=top->next;
    length--;
    return top->data;
}

void displaystack()
{
    while(top->next!='\0')
    {
        cout<<top->data<<endl;
    top=top->next;
    }
}

int getlength()
{
    return length;
}

private:
    Node *top;
    int length;

};

void main()
{
    clrscr();
    Stack s;
    s.push(9);
    s.push(8);
    s.push(7);
    s.push(6);
    s.push(5);
    s.push(3);
    s.displaystack();
    int len=s.getlength();
    cout<<"length of stack is "<<len<<endl;
    getch();
}

它只打印以下内容: 3 堆栈的长度是 6

--------xxxxxxx--------xxxxxxxx--------xxxxxxx-----------xxxxxxxxxxxxx------------ --

编辑后的代码如下所示:并且也可以工作!(感谢@Kaathe):P

#include<iostream.h>
#include<conio.h>

class Node
{
protected:
Node* next;
int data;

public:

Node(int d){data=d;}
friend class Stack;
};

class Stack
{
public:
Stack(){top->next=NULL;length=0;}
~Stack()
{
     while(top!=NULL)
 {
   Node* toDelete=top;
   top=top->next;
   delete toDelete;
 }

}

void push(int d)
{
Node *n=new Node(d);
n->next=top;
top=n;
length++;
}

int pop()
{
 Node* oldtop=top;
 top=top->next;
 int oldtopdata=oldtop->data;
 delete(oldtop);
 --length;
 return oldtopdata;
}

void displaystack()
{
Node* current=top;
while(current->next!=NULL)
    {
    cout<<current->data<<endl;
    current=current->next;
    }
}

int getlength()
{
return length;
}

private:
Node *top;
int length;

};
4

4 回答 4

2

当你push想要创建一个全新的Node,将其数据设置为 value d,并将其指向堆栈的旧顶部。然后,您可以将堆栈的顶部设置为这个新节点。您实际上根本不需要修改旧的顶级节点。

所以 push 可以读成:

void push(int d)
{
    Node* newTop = new Node(d);
    newTop->next = top;
    top = newTop;
    ++length;
}

我只是注意到pop,当您丢弃顶部节点并返回其下方节点中的数据时,它的行为也不会像预期的那样。也许你可以写:

int pop() 
{
    Node* oldTop = top;
    top = top->next;
    int oldTopData = oldTop->data;
    delete(oldTop);
    --length;
    return oldTopData;
}

阻止人们弹出空堆栈可能也是一个好主意(例如,通过length >= 1pop().

最后,如果被调用,会通过丢失指向顶部节点的指针来displaystack破坏对象。Stack也许这样会更好:

void displayStack()
{
    Node* currNode = top;
    while(currNode->next != nullptr)
    {
        std::cout << currNode->data << std::endl;
        currNode = currNode->next;
    }
}

对我来说,用 a 结束链表更有意义nullptr

此外,堆栈应该有一个析构函数,它就是它delete的全部Node——我会让你写那个;)

于 2013-08-25T14:46:11.357 回答
0

如果您的代码中仍然有这个,如果您的程序有效,我会感到惊讶:

Stack(){top->next=NULL;length=0;}

解决方案留给读者练习;-)

于 2013-08-25T16:46:42.737 回答
0

当您打印 (in displaystack) 时,您应该使用临时变量而不是破坏性地更新顶部变量。

为了避免内存泄漏,pop()您还应该delete使用之前分配的节点new

于 2013-08-25T14:53:18.797 回答
0

您可以替换while(top->next!='\0')while(top!='\0') 它应该可以工作......

于 2016-01-28T14:44:10.510 回答