堆栈知识整理

本文仅是我用来整理学过的东西,可能有些许错误,欢迎各位大佬指正。

栈的性质

1.像一个杯子一样,不断往杯底压入数据,数据从杯口输出。(先进后出,后进先出)

顺序栈

1.即用数组来储存栈。

优点:简单方便。

缺点:使用静态数组储存,大小固定,可能会上溢,还会有存储空间的浪费。

2.拥有的变量:一个指向数组的指针,数组的实际大小(即你要开多大的数组),当前栈顶的位置。

3.拥有的函数:压入,弹出,获得栈顶元素,判断栈满,栈空,将栈设为空。

下面是一般栈的定义。

class Stack
{
    private:
      char *data;
      int size;
      int top;
    public:
      Stack();
      Stack(int s);
      ~Stack();
      void  push( char ch );  //成员函数:入栈
      void pop( ); //成员函数:出栈
      char getTop( );     //成员函数:获得栈顶元素(不出栈)
      bool  isEmpty( );      //成员函数:栈是否为空
      bool  isFull( );      //成员函数:栈是否满
      void setNull();      //设置栈为空

};

4.构造函数(初始化)

1.创建一个数组(如果是有参函数,数组大小为传入的参数值)

2.数组实际大小设为0;

3.top=-1;

5.析构函数:因为是new语句申请的数组空间所以要主动删除。

其他函数的过程很简单这里直接放代码。

Stack::Stack()
{
    size=MAX_SIZE;
    data=new char[size];
    top=-1;
}
Stack::Stack(int s)
{
    size=s;
    data=new char[size];
    top=-1;
}
Stack::~Stack()
{
    delete [] data;
}
void Stack::push(char ch)
{
    if(isFull())return;
    data[++top]=ch;
}
void Stack::pop()
{
    if(isEmpty())return;
    top--;
}
char Stack::getTop()
{
    return data[top];
}
bool Stack::isEmpty()
{
    if(top==-1)
    {
        return true;
    }
    else
    {
        return false;
    }
}
bool Stack::isFull()
{
    if(top+1==size)
    {
        return true;
    }
    else
    {
        return false;
    }
}
void Stack::setNull()
{
    top=-1;
}

注意:其中的函数的返回类型可以改成bool。

总结来说顺序栈很简单,容易理解,但如果要存储的数据数量变化大的话就不建议使用,平常一般使用链栈。

链栈

1.用指针将一个个的数据串起来。

小知识点:数组在申请存储空间的时候,是申请一整块的完整空间,所以数组不能开得很大。

所以链栈的优缺点和顺序栈是相反的。

优点:不浪费空间,空间的利用率高。

缺点:就是太难理解,对于指针不好的小伙伴不友好。

2.定义结构体

一个数据变量data(我在例子中写的是ch,问题不大)

一个指针域指向结构体这种类型(额,一般的结构体好像都这么定义,包括后面的其它数据结构)

struct node
{
    char ch;//字符
    struct node* next;//指针
};

其实可以用类模板(简单点说就是数据变量的类型不确定)

不知道的小伙伴也没关系,其实我也不清楚......

3.拥有的成员

一个指向头结点的指针first,成员函数功能和顺序栈的差不多

注意:first本身的就是第一个有效结点

class LinkStack
{
public:
    /** Default constructor */
    LinkStack();
    /** Default destructor */
    ~LinkStack();
    /**< 数据压入堆栈 */
    void push(char ch);
    /**< 弹出栈顶数据 */
    void pop();
    /**< 读取栈顶数据 */
    char getTop();
    /**< 判断栈是否为空 */
    bool isEmpty();
    /**< 从顶部打印堆栈 */
    void displayFromTop();
private:
    struct node* first;//!< Member variable "指向栈顶的元素"
};

4.函数的实现

 1.构造函数

LinkStack::LinkStack()
{
    first = NULL;
}

 2.push函数(压入数据)

   使用头插法

void LinkStack::push(char x)
{
    struct node* p =new struct node;
    p->ch = x;
    p->next = first;
    first = p;
    return;
}

3.pop函数(弹出数据,但不输出)

void LinkStack::pop()
{
    if (isEmpty())
    {
        return;
    }
    cout << first->ch << endl;
    first = first->next;
    return;
}

 输出语句可写可不写

4.getTop函数(获得最后压入的函数,但不弹出这个数据)

 由于是头插法插入的所以first其实指向的最后一个插入的数

例如输入abcd

实际插入顺序是 

1.first->a

2.first->b->a

3.first->c->b->a

4.first->d->c->c->a

所以获取头顶元素就是获取first的data值

char LinkStack::getTop()
{
    if (isEmpty())
    {
        cout << "栈为空" << endl;
        return 0;
    }
    return first->ch;
}

5.isEmpty函数(判断栈是否为空)

bool LinkStack::isEmpty()
{
    if (first== NULL)
    {
        return true;
    }
    return false;
}

6.displayFromTop函数(从头开始依次输出数据)

void LinkStack::displayFromTop()
{
    struct node* p = first;
    if (isEmpty())return;
    while (p != NULL)
    {
        cout << p->ch;
        p = p->next;
    }
    return;
}

7.析构函数

放到最后是因为我觉得最难理解

先看一下代码

LinkStack::~LinkStack()
{
    struct node* p = first;
    struct node* q = first->next;
    while (q!=NULL)
    {
        delete p;
        p = q;
        q = q->next;
    }
    delete p;
    return;
}

由于我的判断条件是q!=NULL,所以最后的情况是p指向最后一个数据(且没删除)q为空指针。

所以最后要删除p结点的数据。

STL的用法

因为在平常的使用中不可能每次想用栈就把栈类重新写一遍,所以我们可以使用C++已经为我们准备好的栈类

#include<stack>     //头文件

stack<int> s;       //声名一个储存int类型的栈   名字叫s
stack<string> s;    //声名一个储存string类型的栈   名字叫s

其中的函数功能与我上面写的差不多。

如果不记得有那些函数,可以打出栈名然后按一下 '.' 就会出现栈拥有的函数,基本是看名字就知道是什么意思。

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值