C++ 跟踪堆栈C+的链表实现中的堆栈大小+;

C++ 跟踪堆栈C+的链表实现中的堆栈大小+;,c++,linked-list,stack,C++,Linked List,Stack,我正在研究ItemType(当前设置为double,但可以更改)值堆栈的链表实现。虽然我的代码编译得很好,但我已经意识到我的size方法效率很低,因为它使用迭代来获得链表的大小——O(n)时间复杂度——当它可以简单地将大小存储为节点字段时,在我的其他方法中更新它,然后返回该值——改进该方法,使其具有O(1)时间复杂度。然而,不幸的是,我在计算如何集成这个新的大小字段时遇到了一些问题,特别是如何初始化它的值,我的编译器一直告诉我它无法编辑。那么,我的问题是如何将大小实现为节点类的一个字段(或者应该

我正在研究ItemType(当前设置为double,但可以更改)值堆栈的链表实现。虽然我的代码编译得很好,但我已经意识到我的size方法效率很低,因为它使用迭代来获得链表的大小——O(n)时间复杂度——当它可以简单地将大小存储为节点字段时,在我的其他方法中更新它,然后返回该值——改进该方法,使其具有O(1)时间复杂度。然而,不幸的是,我在计算如何集成这个新的大小字段时遇到了一些问题,特别是如何初始化它的值,我的编译器一直告诉我它无法编辑。那么,我的问题是如何将大小实现为节点类的一个字段(或者应该在其他地方实现它?),以及应该在代码中的何处初始化和更新它

下面是链接列表堆栈的头文件:

#ifndef DBLSTACK_H
#define DBLSTACK_H


typedef double ItemType; // stack currently holds doubles


class DblStack
{
private:
    //Node class
    class Node
    {
    public:
        double data;
        Node *next;

        // Node constructor
        Node(double value, Node * link = 0)
        {
            data = value;
            next = link;
        }
    };

    typedef Node * NodePtr;

    // Data members
    NodePtr myTop;  //points to top of stack

  public:
    // Class Constructor
    DblStack();

    // Copy Constructor
    DblStack(const DblStack& rhs);

    // Class Deconstructor
    ~DblStack();

    // Assignment operator
    // Assigns a stack to another
    const DblStack& operator= (const DblStack& rhs);

    // isEmpty
    // Checks if the stack is empty
    bool isEmpty() const;

    // push
    // Pushes an item on top of the stack.
    void push(const ItemType& item);

    // pop
    // Pops the top item off the stack.
    void pop();

    // top
    // Returns the top item of the stack without popping it.
    ItemType top() const;

    // size
    // Returns the number of items on the stack.
    size_t size() const;

};

#endif
这是我的源文件:

#include <cstddef>  //for NULL
#include <stdexcept>
#include "DblStack.h"
using namespace std;

// Class Constructor
DblStack::DblStack()
: myTop(0)
{
}


// Copy Constructor
DblStack::DblStack(const DblStack& rhs)
{
    myTop = 0;
    if (!rhs.isEmpty())
    {
        // Copy first node
        myTop = new DblStack::Node(rhs.top());

        // Set pointers to run through stack
        DblStack::NodePtr lastPtr = myTop;
        DblStack::NodePtr origPtr = rhs.myTop->next;
        while (origPtr != 0)
        {
            lastPtr->next = new DblStack::Node(origPtr->data);
            lastPtr = lastPtr->next;
            origPtr = origPtr->next;
        }
    }
}



// Class Deconstructor
DblStack::~DblStack()
{
    // Set pointers to run through stack
    DblStack::NodePtr curr = myTop, next;
    while (curr != 0)
    {
        next = curr->next;
        delete curr;
        curr = next;
    }
}


// Assignment operator
// Assigns a stack to another
const DblStack& DblStack::operator= (const DblStack& rhs)
{
    if (this != &rhs)
    {
        this->~DblStack();
        if (rhs.isEmpty())
        {
            myTop = 0;
        }
        else
        {
            DblStack tmp(rhs);  // Call copy constructor
            std::swap(myTop, tmp.myTop);
        }
    }
    return *this;
}


// isEmpty
// Checks if the stack is empty
bool DblStack::isEmpty() const
{
    return (myTop == 0);
}


// push
// Pushes an item on top of the stack.
void DblStack::push(const ItemType& item)
{
    myTop = new DblStack::Node(item, myTop);
}


// pop
// Pops the top item off the stack.
void DblStack::pop()
{
    if (!isEmpty())
    {
        DblStack::NodePtr ptr = myTop;
        myTop = myTop->next;
        delete ptr;
    }
    else
    {
        throw std::underflow_error("Stack is empty");
    }
}


// top
// Returns the top item of the stack without popping it.
ItemType DblStack::top() const
{
    if (!isEmpty())
    {
        return myTop->data;
    }
    else
    {
        throw std::underflow_error("Stack is empty");
    }
}


// size
// Returns the number of items on the stack.
size_t DblStack::size() const
{
    size_t size = 0;
    DblStack::NodePtr ptr;
    for (ptr = myTop; ptr != 0; ptr = ptr->next)
    {
        size++;
    }
    return size;
}
#包含//表示空
#包括
#包括“DblStack.h”
使用名称空间std;
//类构造函数
DblStack::DblStack()
:myTop(0)
{
}
//复制构造函数
DblStack::DblStack(常量DblStack和rhs)
{
myTop=0;
如果(!rhs.isEmpty())
{
//复制第一个节点
myTop=newdblstack::Node(rhs.top());
//设置要在堆栈中运行的指针
DblStack::NodePtr lastPtr=myTop;
DblStack::NodePtr origPtr=rhs.myTop->next;
while(origPtr!=0)
{
lastpr->next=newdblstack::Node(origPtr->data);
lastPtr=lastPtr->next;
origPtr=origPtr->next;
}
}
}
//类解构器
DblStack::~DblStack()
{
//设置要在堆栈中运行的指针
DblStack::NodePtr curr=myTop,next;
while(curr!=0)
{
下一步=当前->下一步;
删除curr;
curr=next;
}
}
//赋值运算符
//将堆栈分配给另一个堆栈
const DblStack&DblStack::operator=(const DblStack&rhs)
{
如果(此!=&rhs)
{
这个->~DblStack();
if(rhs.isEmpty())
{
myTop=0;
}
其他的
{
DblStack tmp(rhs);//调用复制构造函数
std::swap(myTop,tmp.myTop);
}
}
归还*这个;
}
//空空如也
//检查堆栈是否为空
bool DblStack::isEmpty()常量
{
返回值(myTop==0);
}
//推
//将项目推到堆栈顶部。
void DblStack::push(const ItemType和item)
{
myTop=新的DblStack::节点(项,myTop);
}
//流行音乐
//从堆栈中弹出顶部项目。
void DblStack::pop()
{
如果(!isEmpty())
{
DblStack::NodePtr ptr=myTop;
myTop=myTop->next;
删除ptr;
}
其他的
{
抛出标准::下溢错误(“堆栈为空”);
}
}
//顶
//返回堆栈的顶部项而不弹出它。
ItemType DblStack::top()常量
{
如果(!isEmpty())
{
返回myTop->data;
}
其他的
{
抛出标准::下溢错误(“堆栈为空”);
}
}
//大小
//返回堆栈上的项数。
size\u t DblStack::size()常量
{
大小\u t大小=0;
DblStack::NodePtr ptr;
对于(ptr=myTop;ptr!=0;ptr=ptr->next)
{
大小++;
}
返回大小;
}

虽然改进我的大小方法是这个问题的主要目标,但我也非常感谢您对优化我的代码提出的任何其他建议。谢谢大家!

将size作为
DblStack
的成员包含,并修改其其他方法以使其保持最新。

将size作为
DblStack
的成员包含,并修改其其他方法以使其保持最新。

您需要将size成员变量添加到DblStack类中:

class DblStack
{
private:
    size_t size;
// ...
}
第一次构造DblStack时,该DblStack中没有任何内容,因此其大小应为0:

DblStack::DblStack()
    : myTop(0)
    , size(0)
{ }
现在你需要考虑什么时候尺寸会改变!您应该发现,它改变的唯一情况是当项目从堆栈中被推送或弹出时。因此,您希望推送和弹出方法能够反映这一点:

// Push increases stack size
size++;

// Pop decreases stack size
size--;
最后,您可以更改size()方法以仅返回大小:

size_t size() const { return size; }
您需要向DblStack类添加一个大小成员变量:

class DblStack
{
private:
    size_t size;
// ...
}
第一次构造DblStack时,该DblStack中没有任何内容,因此其大小应为0:

DblStack::DblStack()
    : myTop(0)
    , size(0)
{ }
现在你需要考虑什么时候尺寸会改变!您应该发现,它改变的唯一情况是当项目从堆栈中被推送或弹出时。因此,您希望推送和弹出方法能够反映这一点:

// Push increases stack size
size++;

// Pop decreases stack size
size--;
最后,您可以更改size()方法以仅返回大小:

size_t size() const { return size; }

这个问题似乎离题了,因为它是关于代码审查的。应该在CodeReview.SE上进行??!!为什么?
const-DblStack&DblStack::operator=(const-DblStack&rhs){DblStack-temp(rhs);std::swap(temp.myTop,myTop);return*this;}
这是operator=需要做的所有事情。这个问题似乎与主题无关,因为它是关于代码审阅的。这应该在CodeReview.SE上进行。
this->~DblStack()??!!为什么?
const DblStack&DblStack::operator=(const DblStack&rhs){DblStack temp(rhs);std::swap(temp.myTop,myTop);return*this;}
这就是您的operator=需要做的一切。“…并修改DblStack的其他方法…”抱歉,我误解了您答案的第二部分。“…并修改DblStack的其他方法…”,我误解了你回答的第二部分。