欢迎访问宙启技术站
智能推送

如何实现C++栈(stack)的模板类

发布时间:2023-05-15 15:32:14

模板类是C++中的一个重要特性,允许我们使用一套代码生成多个不同类型的类。栈(stack)是计算机科学中常用的一种数据结构,可用于存储和管理内存中的数据。在本文中,我们将介绍如何实现C++的栈模板类。

1. 栈的基本概念

在计算机科学中,栈(stack)是一种后进先出(LIFO)的数据结构。它有两个基本操作:压入(push)和弹出(pop)。压入操作将元素添加到栈的顶部,而弹出操作将元素从栈的顶部删除。栈还具有一个重要的属性,即它的访问限制是严格的。只有在栈顶的元素才可以被访问和操作。

2. 实现C++栈的模板类

我们可以使用C++模板类来实现一个通用的栈类,如下所示:

template<typename T>
class Stack {
   private:
      struct Node {
         T element;
         Node* next;
         Node(const T& el, Node* n = nullptr) : element(el), next(n) {}
      };
      Node* topNode;

   public:
      Stack() : topNode(nullptr) {}

      ~Stack() {
         while(!isEmpty())
            pop();
      }

      void push(const T& element) {
         topNode = new Node(element, topNode);
      }

      void pop() {
         if(isEmpty())
            return;
         Node* temp = topNode;
         topNode = topNode->next;
         delete temp;
      }

      const T& top() const {
         if(isEmpty())
            throw std::out_of_range("stack is empty");
         return topNode->element;
      }

      bool isEmpty() const {
         return topNode == nullptr;
      }

      size_t size() const {
         size_t count = 0;
         Node* current = topNode;
         while(current != nullptr) {
            count++;
            current = current->next;
         }
         return count;
      }
};

3. 解析实现细节

该实现使用了一个私有结构体Node来存储元素和指向栈顶下一个元素的指针。Stack类有一个指向栈顶节点的指针topNode,它可以通过push和pop操作被更改。

在push操作中,我们只需创建一个新节点,该节点将成为新元素堆栈中的新顶部。新节点的下一个指针将指向旧的顶部元素。注意,我们使用new操作符为新节点分配内存。

在pop操作中,我们需要检查堆栈是否为空,然后,我们将 个节点删除,并更新topNode指针,以使其指向新的顶部元素。

在top操作中,我们会将异常抛出,以防止对空堆栈执行操作。否则,我们仅返回topNode的值。

在isEmpty操作中,我们仅通过检查topNode指针是否为空来检查堆栈是否为空。

在size操作中,我们使用while循环遍历堆栈,并对每个节点计数,直到达到null节点。

4. 栈模板类的应用

现在我们已经定义了一个通用的栈模板类,可以使用它来管理许多类型的数据。例如,我们可以使用Stack来实现一个简单的浏览器前进后退历史记录:

Stack<std::string> backStack;  // 后退记录
Stack<std::string> forwardStack;  // 前进记录
std::string currentUrl;

void goToUrl(std::string url) {
   backStack.push(currentUrl);
   currentUrl = url;
   forwardStack.clear();
}

void back() {
   if(backStack.isEmpty())
      return;
   forwardStack.push(currentUrl);
   currentUrl = backStack.top();
   backStack.pop();
}

void forward() {
   if(forwardStack.isEmpty())
      return;
   backStack.push(currentUrl);
   currentUrl = forwardStack.top();
   forwardStack.pop();
}

在此示例中,我们使用两个堆栈来存储前进和后退的URL历史记录。当用户浏览一个新的URL时,我们将当前URL添加到后退堆栈中,并清空前进堆栈。当用户要求“后退”时,我们从后退堆栈中取出URL,并将其添加到前进堆栈中。当用户要求“前进”时,我们从前进堆栈中取出URL,并将其添加到后退堆栈中。这对用户感知历史记录和导航非常有用。

5. 总结

在本文中,我们介绍了如何使用C++模板类来实现栈。我们定义了一个通用的Stack类,它可以管理任何类型的数据。我们还介绍了栈的基本概念和堆栈操作的实现细节。最后,我们给出了一个实际应用场景,浏览器中前进后退历史记录的实现。