嵌入式学习一阶段——C语言:数据结构(3)

栈(stack)是仅限定在表尾进行插入和删除的线性表
    栈就是一个线性表,只不过,栈的insert和delete 只能在表尾
    普通的线性表,是不是可以在任意位置进行insert和delete
    LIFO:Last in first out   后进先出
栈顶(top):进行插入和删除操作一端
栈底(bottom)
    栈其实是我们计算机科学当中,更多来说,是一种思想,“先进后出的思想”,在很多的算法或者应用当中,
    需要用到“先进后出的思想”,我们就可以用栈来实现。
例子:
    1、假设有一个栈S,入栈元素的顺序是ABCD,请问这四个元素的出栈顺序有哪些??总数是??

2、有五个元素,其入栈的次序为A,B,C,D,E,在各种可能的出栈的次序中,第一个出栈元素为C,并且第二个元素为D的出栈序列有哪几种?? cdeba cdbea cdbae 本质: 是一个“先进后出”(仅在表尾/栈顶那一段进行插入和操作的)线性表

栈的实现

存储结构(物理结构):
    顺序结构:用一组地址连续的空间来存储数据元素
    链式结构:用地址不连续的空间来存储数据元素,可能需要额外的开辟一些空间,来存储
    “数据元素之间的逻辑关系”。
​
----栈的基本操作-----
InitStack  初始化一个栈
DestoryStack    销毁一个栈
ClearStack      清空一个栈
StackEmpty      判断一个栈是否为空
StackLength     返回栈中的元素的个数,也就是栈的长度
Push            元素入栈,把一个元素加入到栈中
Pop             出栈,把栈顶元素给干掉
GetTop          返回一个栈顶元素,但是不出栈

顺序栈

seqStack
    用一组地址连续的空间来存储数据元素   数组
    typedef int SElemType;
    typedef strcut SeqStack
    {
        //SElemType data[1024];       //data 用来存储栈中的元素
        SElemType *data;              //data 指向的空间用来存储栈中的元素  “动态数组”
                                    //data = malloc(maxlen*sizeof(SElemType)) ;
        int maxlen;                 //栈中最多可以存多少个元素
        int top;                    //栈顶元素的下标
                                    //-1  表示空栈
    }SeqStack;
​
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"seqstack.h"

/*
@InitStack:初始化一个栈
@maxl:栈的最大空间
@rerurn:返回一个栈的指针
*/
SeqStack* InitStack(int maxl)
{
    SeqStack * stack=malloc(sizeof(SeqStack));
    stack->maxlen=maxl;
    stack->data=malloc(maxl*sizeof(SElemtype));
    stack->top=-1;//空栈
    return stack;
}


/*
@Push:入栈
@SeqStack* s:栈头
@SElemtype x:要入栈的元素
*/
int Push(SeqStack* s,SElemtype x)
{
    if(s==NULL||s->top==s->maxlen-1)
    {
        printf("栈溢出\n");
        return 0;//入栈失败
    } 
        s->data[++s->top]=x;
    return 1;//入栈成功
}
/*
@Pop:出栈
@SeqStack* s:栈头
@SElemtype* e:要出栈的元素地址
*/
int Pop(SeqStack* s,SElemtype *e)
{
    if(s==NULL||s->top==-1)
    {
        return 0;//出栈失败
    } 
    *e=s->data[s->top--];
    return 1;
}

//销毁一个栈
void DestoryStack(SeqStack* s)
{
    if(s==NULL)
    return;
    free(s->data);
    free(s);
}



//清空一个栈
void ClearStack(SeqStack* s)
{
    if(s==NULL)
    return;
    while(s->top!=-1)
    s->data[s->top--]=0;
    s->maxlen=0;
}

//判断一个栈是否为空
int StackEmpty(SeqStack* s)
{
    if(s==NULL||s->top==-1)
    return 0;//栈为空
    else
    return 1;//栈不为空
}

//返回一个栈的元素个数
int StackLength(SeqStack* s)
{
    if(s==NULL||s->top==-1)
    return 0;
    return s->top+1;//栈的元素个数
}

//返回一个栈顶元素,但是不出栈
int GetTop(SeqStack* s,SElemtype* e)
{
    if(s==NULL||s->top==-1)
    return 0;//栈为空
    *e=s->data[s->top];
    return 1;//栈不为空
}
/*
@doubleInitStack:初始化一个共享栈
@maxl:栈的最大空间
@rerurn:返回一个栈的指针
*/
doubleSeqStack* doubleInitStack(int maxl)
{
    doubleSeqStack * stack=malloc(sizeof(doubleSeqStack));
    stack->maxlen=maxl;
    stack->data=malloc(maxl*sizeof(SElemtype));
    stack->top1=-1;//第一个栈空栈
    stack->top2=maxl;//第二个栈空栈
    return stack;
}

/*
@doublePush:共享栈入栈
@doubleSeqStack* s:栈头
@SElemtype x:要入栈的元素
@stacknumber:哪个栈
*/
int doublePush(doubleSeqStack* s,SElemtype x,int stacknumber)
{
    if(s==NULL||s->top1+1==s->top2)
    {
        printf("栈溢出\n");
        return 0;//入栈失败
    } 
    if(stacknumber==1)//往栈1添加元素
    s->data[++s->top1]=x;
    if(stacknumber==2)//往栈2添加元素
    s->data[--s->top2]=x;
    return 1;//入栈成功
}

/*
@doublePop:共享栈出栈
@doubleSeqStack* s:栈头
@SElemtype* e:要出栈的元素地址
@stacknumber:哪个栈
*/
int doublePop(doubleSeqStack* s,SElemtype *e,int stacknumber)
{
    if(s==NULL)
    {
        return 0;//出栈失败
    } 
    if(stacknumber==1)
    {
        if(s->top1==-1)
        {
            return 0;
        }
        *e=s->data[s->top1--];
    }
    else
    {
         if(s->top2==s->maxlen)
        {
            return 0;
        }
        *e=s->data[s->top2++];
    }
    
    return 1;
}

链式栈

//数据节点:
typedef int SElemType;
​
//数据结点
typedef struct SNode
{
​
    SElemType data ;    //保存栈中的一个元素
    struct SNode* next;
    struct SNode* prev;
​
}SNode;
​
//头节点
typedef struct LinkedStack
{
    //栈顶  指向链式栈的最后一个元素
    SNode * top;
    //栈底元素
    SNode * first;
    //栈中的元素个数
    int Nodenum;
}LinkedStack;
#include<stdio.h>
#include<stdlib.h>
#include"liststack.h"

//@InitStack 初始化一个链式栈
//@return 返回一个链式栈的栈头
listStack* InitStack(void)
{
    listStack* lstack=(listStack*)malloc(sizeof(listStack));
    lstack->top=NULL; 
    lstack->nodenum=0;
    lstack->first=NULL;
    return lstack;
}

//@Push:入栈
//@listStack* ls:栈的头节点
//@SElemtype x:入栈的元素
int Push(listStack* ls,SElemtype x)
{
    if(ls==NULL)
    return 0;//失败
    ls->nodenum+=1;
    SNode* p=malloc(sizeof(SNode));
    p->data=x;
    p->next=NULL;
    p->prev=NULL;
    if(ls->top==NULL)
    {
        ls->top=p;
        ls->first=p;      
    }
    else
    {
        ls->top->next=p;
        p->prev=ls->top;
        ls->top=p;
    }
    return 1;//入栈成功
}

/*
@Pop:出栈
@SeqStack* s:栈头
@SElemtype* e:要出栈的元素地址
*/
int Pop(listStack* ls,SElemtype *e)
{
    if(ls==NULL||ls->nodenum==0)
    {
        return 0;//出栈失败
    } 
    *e=ls->top->data;
    ls->nodenum-=1;
    SNode* px=ls->top;
    if(ls->nodenum==0)
    {
        ls->first=NULL;
        ls->top=NULL;
        free(px);
    }
    else
    {
        ls->top=px->prev;
        px->prev->next=NULL;
        free(px);
    }      
    return 1;
}

//返回一个栈顶元素,但是不出栈
int gettop(listStack* ls,SElemtype* e)
{
    if(ls==NULL||ls->nodenum==0)
    return 0;//栈为空
    *e=ls->top->data;
    return 1;//栈不为空
}

//@destroyliststack 销毁一个链式栈
void destoryliststack(listStack* ls)
{
    if(ls==NULL)
    return;
    clearliststack(ls);
    free(ls);
}
//@Clearliststack 清空一个链式栈
void clearliststack(listStack* ls)
{
    if(ls==NULL||ls->top==NULL)
    return;
   SNode* px=ls->first;
   while (px!=NULL)
   {
        ls->first=px->next;
        if(px->next!=NULL)
        {
            px->next->prev=NULL;
        }
        px->next=NULL;
        free(px);
        px=ls->first;
        
   }
    ls->top=NULL;
    ls->nodenum=0;
   
}
//判断一个栈是否为空
int liststackempty(listStack* ls)
{
    if(ls==NULL||ls->nodenum==0)
    return 0;//栈为空
    else
    return 1;//栈不为空
}
//返回一个栈的元素个数
int liststacklength(listStack* ls)
{
    if(ls==NULL||ls->nodenum==0)
    return 0;
    return ls->nodenum;//栈的元素个数
}

两栈的共享空间

栈的一个应用

后缀表达式

后缀表达式所有的运算符在操作数的后面!!

中缀表达式

中缀表达式的运算符散布在操作其中!!

作业

1、求一个表达式的值,表达式是以字符串的形式给出 表达式:整数的 +-/ “5+304+7/3”

int expression(char *e)
{
    //你得先初始化两个栈
    //操作数 d
    //运算符 s
    while(*e)
    {
        //先解析一个操作数
        //直接就入栈
        while(1)
        {
            //再解析一个运算符,待入栈的运算符
            if(待入栈的运算符 比 栈顶的运算符 高)
            {
                //直接入栈s
                break;
            }
            else
            {
                //把运算符栈 栈顶元素 pop
                //把操作数栈 栈顶的元素 pop 两次
                // a+b 
                //再把结果入操作数的栈
            }
            
        }
    }
    while(运算符栈不为空)
    {
        //把运算符栈 栈顶元素 pop
            //把操作数栈 栈顶元素 pop 两次
             // a+b 
                //再把结果入操作数的栈
    }
​
    //最后的结果保存在操作数的栈中!!
    GOOD LUCK FOR YOU !!!!
}
​
​
int is_hiht(char ch1 , char ch2)
{
    if((ch1 == '*' || ch1 == '/' || ch1 == '%')&& (ch2 == '+' ||ch2 == '-'))
    {
        return 1;
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值