数据结构栈的两种类型

前言

1、理解顺序栈的定义,以及对元素的进栈,出栈,读栈顶元素

2、理解链栈的定义,以及对元素的进栈,出栈,读栈顶元素


提示:以下是本篇文章正文内容,下面案例可供参考

一、栈:只能在一端进行插入删除操作的线性表

  1. 栈顶:可以进行插入删除操作
  2. 栈底:不能进行任何操作
  3. 特点:先进后出(FILO) 

1.1 顺序栈

#define MaxSize 10             //定义栈中元素的个数
typedef struct {
    ElemType data[MaxSize];    //存放元素
    int top;                   //定义栈顶指针
}SqStack;

//栈顶指针:S.top,初始值为-1,栈顶元素:S.data[S.top]
//栈空条件:S.top==-1,栈满条件:S.top==MaxSize-1,栈长:S.top-1

//初始化
void InitStack(SqStack &S){
    S.top=-1;       //初始化栈顶指针
}
//判断栈是否为空
Bool StackIsEmpty(SqStack &s){
    if(S.top==-1)
        return true;  //栈空
    else
        return false; //栈不空
}
//进栈
Bool Push(SqStack &s,Elemtype x){
    if(S.top==MaxSize-1) //栈满,报错
        return false;
    S.top=S.top+1;
    S.data[S.top]=x;
    //S.data[++S,top]=x;   //指针先+1,在入栈
    return true;
}
//出栈
Bool Pop(SqStack &s,ElemType &x){
    if(S.top==-1)       //栈空报错
        return false;
    S.data[S.top]=x;
    S.top=S.top-1;
    //S.data[S.top--]=x;  //先出栈,指针再-1
    return true;
}
//读取栈顶元素
Bool Pop(SqStack &s,ElemType &x){
    if(S.top==-1)       //栈空报错
        return false;
    x=S.data[S.top];    //x获取栈顶元素的值
    return true;
}

当栈顶指针初始化为S.top=0时: 

//当S.top的初始值为0时,栈空条件:s.top==0,栈满条件:S.top==MaxSize,栈长:S.top
//初始化
void InitStack(SqStack &S){
    S.top=0;       //初始化栈顶指针
}
//判断栈是否为空
Bool StackIsEmpty(SqStack &s){
    if(S.top==0)
        return true;  //栈空
    else
        return false; //栈不空
}
//进栈
Bool Push(SqStack &s,Elemtype x){
    if(S.top==MaxSize) //栈满,报错
        return false;
    S.data[S.top]=x;
    S.top=S.top+1;
    //S.data[S,top++]=x;   //先入栈,再指针+1
    return true;
}
//出栈
Bool Pop(SqStack &s,ElemType &x){
    if(S.top==0)       //栈空报错
        return false;
    S.top=S.top-1;
    s.data[s.top]=x;
    //S.data[--S.top]=x;  //指针先-1,在出栈
    return true;
}
//读取栈顶元素
Bool Pop(SqStack &s,ElemType &x){
    if(S.top==0)       //栈空报错
        return false;
    x=S.data[S.top];    //x获取栈顶元素的值
    return true;
}

1.2 链栈: 

不带头结点的链表

//链栈结点的定义
typedef struct LinkLNode{
    ElemType data;                 //数据域
    struct LinkLNode *next;        //指针域
}LinkLNode;                        //链栈结点定义

//不带头结点链栈的初始化
void initLinkStack(LinkLNode *&L){             //需要改变栈的内容,用引用型
    L=(LinkLNode*)malloc(sizeof(LinkLNode));  //定义一个新的结点
    L->data=NULL;                              //不建头结点,此结点就是第一个结点 
}

//判断栈空代码
bool isEmpty(LinkLNode *L){        //判断是否为空
    if(L->data==NULL)
        return true;
    else
        return false;
}

//进栈
bool Push(LinkLNode *L,ElemType x){
    LinkLNode *p;
    p=(LinkLNode*)malloc(sizeof(LinkLNode));  //进栈元素申请新的结点
    p->next=NULL;                             //可以避免一些错误
    /*不带头结点链表的头插法*/
    L->data=x;
    p->next=L;
    L=p;
    return true;
}

//出栈
bool Pop(LinkLNode *L,ElemType &x){           //获取栈顶元素的值,使用引用型
    LinKLNode *p;
    if(L->data==NULL)
        return false;
    /*不带头结点链表的删除操作*/
    p=L
    x=p->data;
    L=p->next;
    free(p);
    return true;
}

 带头结点:

//链栈结点的定义
typedef struct LinkLNode{
    ElemType data;                 //数据域
    struct LinkLNode *next;        //指针域
}LinkLNode;                        //链栈结点定义

//带头结点链表的初始化
void initLinkStack(LinkLNode *&L){             //需要改变栈的内容,用引用型
    L=(LinkLNode*)malloc(sizeof(LinkLNode));   //定义一个新的结点
    L->next=NULL;                              //此节点作为头结点,判空条件L->next==NULL
}

//判断栈空代码
bool isEmpty(LinkLNode *L){        //判断是否为空
    if(L->==NULL)
        return true;
    else
        return false;
}

//进栈
bool Push(LinkLNode *L,ElemType x){
    LinkLNode *p;
    p=(LinkLNode*)malloc(sizeof(LinkLNode)); //定义一个新结点
    p->next=NULL;
    /*带头结点的头插法*/
    p->data=x;
    p->next=L->next;
    L->next=p;
    return true;
}

//出栈
bool Pop(LinkLNode *L,ElemType &x){
    LinkLNode *p;
    if(L->next==NULL)                        //栈空,不能进行删除操作
        return false;
    /*带头结点的删除操作*/
    p=L->next;
    x=p->data;
    L->next=p->next;
    free(p);
    return true;
}

 

  有错误请大家评论区留言!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值