栈(C++实现)(《趣学数据结构》大一笔记)

1栈

        栈是一种重要的线性结构

        它是线性表(顺序表、链表)的一种具体形式。也就是说,栈需要通过顺序表或者链表来实现

(等价于栈用顺序存储和用链式存储,称为顺序栈链栈。)

        栈(stack)是一个后进先出(last in first out ,LIFO)的线性表,进出的一端称为栈顶(top),另一端称为栈底(base)。

1.1顺序栈

        顺序栈需要两个指针,base指向栈底,top指向栈顶

typedef struct SqStack{
    ElemType *base;     //栈顶指针
    ElemType *top;      //栈底指针
}SqStack;               //typedef将结构体等价于类型名SqStack

//ElemType是元素的类型

这里属于栈的定义我们还需先定义一个最大的分配空间。(顺序结构都需先定义空间)

#define Maxsize 100;   //空间数值需要根据实际预估确定

1.栈的初始      

        初始化一个空栈,动态分配Maxsize大小的空间,用S.top和S.base指向该空间的基地址。

bool InitStack(SqStack &S){
    S.base=new int [MaxSize];   //分配一段最大容量为Maxsize的内存空间
    if(!S.base) return false;   //空间分配失败
    S.top=S.base;               //首地址等于末地址,此时空栈
    return true;
}

2.入栈

1.前要判断是否达最大容量,若已达,则入栈失败;

2.否则就将元素添加到栈顶栈顶指针向上移动一位(top++)。

bool Push(SqStack &S,int e){       //将元素e添加到栈顶
    if(S.top-S.base == Maxsize)    //判断是否栈满
       return false;
    *S.top+=e;
/*等价于 
*S.top=e;
*S.top++;*/
    return true;
}

3.出栈

1.出栈前判断是否栈空,若栈空,则出栈失败;

2.否则将栈顶元素暂存给栈外的一个变量栈顶指针向下移动一位(top--)。

(注意:因为此时没有销毁出栈元素的空间,所以元素还在那个位置)

bool Pop(SqStack &S,int &e){
    if(S.base==S.top) return false;
    e=*S.top--;
/*等价于
e=*S.top;
*S.top--;*/
    return true;
}

4.取栈顶元素

        取栈顶元素只是把栈顶元素复制一份,对栈无实质性操作,栈内元素个数没有改变。而出栈是指将栈顶指针向下移动一个位置,栈内元素数量-1。

int GetTop(SqStack *S){
    if(S.top!=S.base)      //栈非空
        return *(S.top -1);//返回栈顶元素的值
    else return -1;
}

1.2链栈

定义:

        1.链栈每个节点的地址是不连续的,只需要一个栈顶指针

        2.链栈的每个节点都包含两个域:数据域和指针域

可以将链栈看作一个不带头节点的单链表,但只能在头部进行插入、删除、取值等操作。

链表的结构体定义:

typedef struct Snode{
    ElemType data;             //数据域
    struct Snode *next;        //指向下一个节点的指针
}Snode,*LinkStack;

1.链栈的初始化

        采用跟链表一样的虚拟头节点,让栈顶指针为空。

bool InitStack(LinkStack &S){
    S=NULL;       //使头指针为空
    return true;
}

2.入栈

        入栈是将新元素节点压入栈顶

链栈中栈顶为第一个节点,原第一个节点a,将新节点b插入到节点a前面,修改a指针指向新节点b即可。

bool Push(LinkStack &S,int e){
    LinkStack P;
    p = new Snode;       //生成新节点
    p -> data = e;       //将e存入新节点数据域
    p -> next = S;       //将S的地址赋给新节点指针域
    S = p;               //修改栈顶指针为p,即p成为新的栈顶
    return true;

3.出栈

        出栈就是把栈顶元素删除,让栈顶指针指向下一个节点,并释放该节点内存

bool Pop(LinkStack &S,int &e){  //删除S的栈顶元素,用e保存其值
    LinkStack p;
    if(S==NULL) return false;   //栈空
    e=S->data;                  //用e报存栈顶数据
    p=S;                        //用p保存栈顶元素地址,用来释放
    S=S->next;                  //修改栈顶指针,指向下一个节点(让下一个节点成为新栈顶)
    delete p;                   //释放原栈顶的内存
    return ture;
}

4.取栈顶元素

        将栈顶元素复制一份。

int GetTop(LinkStack &S){        //返回S的栈顶元素,不修改栈顶指针
    if(S!=NULL) return S->data;  //栈非空,返回栈顶元素的值
    else return -1;
}

两者对比

1.在时间效率上一样,顺序栈和链栈的所有基本操作都只需要常数时间

2.在空间效率上,顺序栈需要要先分配固定长度的空间,有可能会造成空间浪费或溢出

链栈每次只分配一个节点,除非没有内存,否则不会溢出,但每个节点都需一个指针域,结构性开销增加

因此若元素个数变化较大,可采用链栈反之采用顺序栈

3.在实际应用中,顺序栈比链栈应用更广泛。

栈的操作

stack <Elemtype> st;   //定义一个栈
Elemtype x;
st.push(x);            //添加x到栈中
st.pop();              //删除栈的栈顶元素
st.push(x);
Elemtype y=st.top();   //将栈顶元素赋给y

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值