编程基础 - 栈(Stack)

本文详细介绍了栈的基本概念、主要方法,并通过C++代码展示了顺序结构和链式结构的栈实现,包括初始化、入栈、出栈、获取栈顶元素等操作,同时提到了双栈共享的顺序结构和链式结构的实现方式。
摘要由CSDN通过智能技术生成

编程基础 - 栈(Stack)

返回分类:全部文章 >> 基础知识

本文意指简明扼要的描述栈,并用C++从零到有的实现栈。

需要一定的数据结构与程序语言的基础,尤其是要了解什么是顺序表。



1 栈的简介(Introduction of Stack)

栈(Stack)又名堆栈。

  • 定义:栈作为一种数据结构,它是一种只能在一端进行插入和删除操作的特殊线性表

    • 允许插入和删除的一端称为栈顶(TOP)
    • 不允许插入和删除的一端称为栈底(BOTTOM)
    • 插入操作称为进栈或入栈(PUSH)
    • 删除操作称为退栈或出栈(POP)
  • 限制:只能在栈顶插入和删除

  • 存储结构:顺序结构或链式结构

  • 运算规则(特点):后进先出(Last-In/First-Out,LIFO)或先进后出(First-In/Last-Out,FILO)

  • 与一般线性表的区别:仅运算规则不同


2 栈的主要方法(Main Methods of Stack)

栈的主要操作包括:

  • 初始化(Initialize)

  • 进栈(Push):插入元素

  • 退栈(Pop):如果栈中有元素,删除栈顶元素;

  • 获取栈顶元素(GetTop):如果栈不为空,获取栈顶元素;

  • 清空栈(Clear):如果栈不为空,则删除所有元素;

  • 判断栈空(IsEmpty):栈空返回true,否则返回false

  • 判断栈满(IsFull):栈满返回true,否则返回false


3 栈的实现(C++ Code)

虽然在各种高级语言中,栈已经都被实现了:

  • 在C++中,使用栈需要加入#include <stack>

  • 在C#中,使用栈需要加入using System.Collection.Generic;

但在这里为了更好的理解它,我们将用C++自己实现栈

提示:以下代码编译器为VC++,属性__declspec(property…)代码在其它编译器可能不通用,如果用其它编译器可删除这一行,直接使用方法代替。

3.1 栈的抽象类(Abstract Class)

首先,我们新建一个头文件起名为Stacks.h。它将包含如下内容:

  • 一些需要的常量(主要是顺序结构需要):

    • 栈的默认最大长度
    • 栈的默认长度增长率
  • 一个栈的模板抽象类:包含了栈的主要方法的虚函数。

  • 一些需要的包含库(#include)

我们同时为这些内容放入 命名空间Stacks(之后所有代码都在它之中) 中:

#pragma once

#include <stdexcept> // Build-in exceptions

namespace Stacks
{
   
    constexpr int DEFAULT_MAX_COUNT = 255; // Max Count of Sequential Structure
    constexpr int DEFAULT_INCREAMENT = 16; // Increament of Sequential Structure

    template<typename T>
    class AbstractStack
    {
   
        public: // Constructor
        virtual ~AbstractStack()
        {
   
        };

        public: // public Properties
        inline virtual int GetCount() = 0;
        __declspec(property(get = GetCount)) int count;

        public: // public Methods
        virtual void Push(T item) = 0;
        virtual T Pop() = 0;
        virtual T Top() = 0;
        virtual T Peek(); // in C#, `Top()` Method is called `Peek()`
        virtual void Clear() = 0;
        virtual bool Empty() = 0;
    };


    template<typename T>
    T AbstractStack<T>::Peek()
    {
   
        return Top();
    }

}
  • #include <stdexcept>:程序异常库,里面有许多常用的异常错误信息

  • DEFAULT_MAX_COUNT:顺序结构的默认长度;

  • DEFAULT_INCREAMENT:顺序结构的默认增长长度;

  • template<typename T> class AbstractStack:栈的模板抽象类(T为元素的类型)

    • int GetCount()int count:是一个属性方法,获取栈内元素个数
    • void Push(T item):入栈
    • T Pop():出栈
    • T Top()T Peek():获取栈顶元素()
    • void Clear():清空栈
    • bool Empty():栈是否为空

Tips
constexpr int可以替换成#define

  • #define DEFAULT_MAX_COUNT 255
  • #define DEFAULT_INCREAMENT 16

有了基类之后,我们将按照栈的结构来分别写代码。

3.2 顺序结构(Sequential Structure)

在顺序结构中,数组存储数据的主要类型。而我们在进行栈操作时,需要一个变量指向栈顶元素,从而顺序结构需要的变量:

  • 元素数组:存储元素

    • 数组初始化的长度
    • 当数组满时,需要增长的长度
  • 栈顶元素下标:标识当前栈顶元素的位置

而在方法上,除了继承下来的方法,我们需要增加一些顺序结构的必要方法:

  • 扩充栈:当栈满时,扩充栈的大小

  • 栈是否满

所以,我们建立一个新的头文件SequentialStack.h来写顺序结构,并将顺序栈命名为SequentialStack

即,我们的最终结构为:

#pragma once

#include "Stacks.h"

namespace Stacks
{
   
    template<typename T>
    class SequentialStack : virtual public AbstractStack<T>
    {
   
        public: // Constructor
        SequentialStack();
        virtual ~SequentialStack() override;

        protected: // protected Fields
        T* m_Items;         // 元素数组
        int m_TopIndex;     // 栈顶下标
        int m_MaxCount;     // 元素数组长度
        int m_Increament;   // 元素数组增长长度

        public: // public Properties
        inline virtual int GetCount() override;
        inline int GetMaxCount();
        inline int GetIncreament();
        inline void PutIncreament(int value);

        __declspec(property(get = GetCount)) int count;
        __declspec(property(get = GetMaxCount)) int maxCount;
        __declspec(property(get = GetIncreament, put 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值