📜  c++中的基本堆栈实现(1)

📅  最后修改于: 2023-12-03 15:14:03.476000             🧑  作者: Mango

C++中的基本堆栈实现

本文将介绍如何使用C++编程语言实现基本的堆栈(stack)数据结构。堆栈是一种后进先出(Last In First Out,LIFO)的数据结构,类似于现实生活中的一堆书或者盘子叠放。

堆栈的基本操作

在实现堆栈之前,我们首先需要了解堆栈的基本操作:

  1. push:将元素添加到堆栈的顶部
  2. pop:从堆栈的顶部移除元素
  3. top:获取堆栈顶部的元素
  4. empty:检查堆栈是否为空
  5. size:获取堆栈中元素的个数

在C++中,我们可以使用数组或者链表来实现堆栈。下面分别介绍这两种实现方法。

数组实现堆栈

首先,使用数组实现堆栈是最简单的方法。你需要声明一个固定大小的数组,然后使用一个指针变量来跟踪堆栈的顶部元素。

const int MAX_SIZE = 100; // 设置堆栈的最大容量

class Stack {
private:
    int stack[MAX_SIZE];
    int top; // 堆栈的顶部元素的索引

public:
    Stack() {
        top = -1; // 初始化堆栈为空
    }

    void push(int element) {
        if (top >= MAX_SIZE - 1) {
            throw "Stack Overflow"; // 堆栈已满,无法插入新元素
        }
        
        stack[++top] = element; // 将元素添加到堆栈顶部
    }
    
    int pop() {
        if (top < 0) {
            throw "Stack Underflow"; // 堆栈为空,无法弹出元素
        }
        
        return stack[top--]; // 弹出并返回堆栈顶部的元素
    }
    
    int peek() const {
        if (top < 0) {
            throw "Stack is Empty"; // 堆栈为空,无法获取顶部元素
        }
        
        return stack[top]; // 返回堆栈顶部的元素,但不弹出
    }
    
    bool empty() const {
        return (top == -1); // 检查堆栈是否为空
    }
    
    int size() const {
        return top + 1; // 返回堆栈中元素的个数
    }
};

上述代码中,我们定义了一个名为Stack的类,其中包含了push、pop、top、empty和size等方法。其中,构造函数用于初始化堆栈为空,throw语句用于抛出自定义的异常信息。

链表实现堆栈

链表实现堆栈相对于数组实现堆栈更加灵活,因为它可以动态地分配内存。我们需要定义一个链表节点类和一个堆栈类。

class ListNode {
public:
    int data; // 存储节点的数据
    ListNode* next; // 指向下一个节点的指针
    
    ListNode(int val) {
        data = val;
        next = nullptr;
    }
};

class Stack {
private:
    ListNode* top; // 堆栈的顶部节点指针

public:
    Stack() {
        top = nullptr; // 初始化堆栈为空
    }

    void push(int element) {
        ListNode* newNode = new ListNode(element); // 创建一个新节点
        
        if (top == nullptr) {
            top = newNode; // 如果堆栈为空,直接将新节点设为顶部节点
        } else {
            newNode->next = top; // 否则将新节点插入到链表的头部
            top = newNode; // 更新顶部节点指针
        }
    }
    
    int pop() {
        if (top == nullptr) {
            throw "Stack Underflow"; // 堆栈为空,无法弹出元素
        }
        
        int element = top->data; // 保存顶部节点的数据
        ListNode* temp = top; // 保存顶部节点的指针
        top = top->next; // 移动顶部节点指针到下一个节点
        delete temp; // 释放堆栈顶部的节点
        
        return element; // 返回被弹出的元素
    }
    
    int peek() const {
        if (top == nullptr) {
            throw "Stack is Empty"; // 堆栈为空,无法获取顶部元素
        }
        
        return top->data; // 返回堆栈顶部的元素,但不弹出
    }
    
    bool empty() const {
        return (top == nullptr); // 检查堆栈是否为空
    }
    
    int size() const {
        int count = 0;
        ListNode* current = top;
        
        while (current != nullptr) {
            count++;
            current = current->next;
        }
        
        return count; // 返回堆栈中元素的个数
    }
};

上述代码中,我们定义了一个名为ListNode的节点类和一个名为Stack的堆栈类。在堆栈类中,我们使用头插法将新节点插入到链表的头部。

示例代码

以下是使用堆栈类的示例代码:

int main() {
    Stack stack;
    
    stack.push(1);
    stack.push(2);
    stack.push(3);
    
    cout << "Size of stack: " << stack.size() << endl; // 输出:Size of stack: 3
    cout << "Top element: " << stack.peek() << endl; // 输出:Top element: 3
    
    stack.pop();
    
    cout << "Size of stack: " << stack.size() << endl; // 输出:Size of stack: 2
    cout << "Top element: " << stack.peek() << endl; // 输出:Top element: 2
    
    return 0;
}

上述代码中,我们首先创建了一个空堆栈,然后使用push方法向堆栈中添加元素,使用peek方法获取堆栈顶部的元素,使用pop方法弹出堆栈顶部的元素,并使用size方法获取堆栈中元素的个数。