栈和队列

一、栈的表示和操作的实现

  1. 定义:(stack)是限定只在表尾进行插入或删除操作的线性表;表头为栈底(bottom),表尾为栈顶(top);不含元素叫空栈;具有后进先出(LIFO)的特点。
  2. 顺序栈的表示和实现
    //-----顺序栈的存储结构-----
    #define MAXSIZE 100  //顺序栈存储最大容量
    typedef struct
    {
        SElemType *base;  //栈底指针
        SElemType *top;   //栈顶指针
        int stacksize;    //栈可用的最大容量
    }SqStack;
    //-----顺序栈的建立-----
    Status InitStack(SqStack &s)
    {
        s.base=new SElemType[MAXSIZE];  //分配容量
        if(!s.base)
            exit(OVERFLOW);  //分配错误
        s.top=s.base;  //空栈
        s.stacksize=MAXSIZE;
        return OK;
    }
    
    *s.top++=e;  //入栈
    e=*--s.top;  //出栈
    *(s.top-1);  //取栈顶元素

     

  3. 链栈的表示和实现

    //-----链栈的存储结构-----
    typedef struct StackNode
    {
        ElemType data;  //数据域
        ElemType StackNode *next;  //指针域
    }StackNode,*LinkStack;
    S=NULL;  //链栈初始化
    
    {//入栈
        p=new StackNode;  //新结点
        p->data=e;
        p->next=S;
        S=p;  //修改栈顶指针为p
    }
    
    {//出栈
        if(S==NULLL)
            return ERROR;  //栈空
        e=S->data;
        p=S;
        S=S->next;
        delete p;
    }

    二、队列的表示和操作的实现

      1.定义:队列(queue)是一种允许在表的一端删除,另一端插入的线性表;允许插入的一端为队尾(rear),允许删除的一端是队头(front);具有先进先出(FIFO)的特点。

       2.循环队列的顺序表示和实现

//-----队列的顺序存储结构-----
#define MAXSIZE 100  //队列可能最大长度
typedef struct
{
    QElemType *base;  //存储空间的基地址
    int front;  //头指针
    int rear;   //尾指针
}SqQueue;

{//初始化循环队列
    Q.base=new QElemType[MAXSIZE];
    Q.front=Q.base=0;  //队列为空
}

{//求队列长度
    length=(Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}

{//入队
    Q.base[Q.rear]=e;  //新元素入队
    Q.rear=(Q.rear+1)%MAXSIZE;  //队尾指针加1
}

{//出队
    e=Q.base[Q.front];  //队头出队
    Q.front=(Q.front+1)%MAXSIZE;  //队头指针加1    
}

       3.链队的表示和实现

//-----队列的链式存储结构-----
typedef struct QNode
{
    QElemType data;
    struct QNode *next;
}QNode,*QueuePtr;

typedef struct
{
    QueuePtr front;  //队头指针
    QueuePtr rear;   //队尾指针
}LinkQueue;

{//初始化空队列
    Q.front = Q.rear =new QNode;
    Q.front->next=NULL;
}

{//入队
    p=new QNode;
    p->data=e;
    p-next=NULL;
    Q.rear->next=p;
    Q.rear=p;
}

{//出队
    if(Q.front=Q.rear)
        return ERROR;  //队列空
    p=Q.front->next;
    e=p->data;
    Q.front->next=p->next;
    if(Q.rear==p)
        Q.rear=Q.front;  //最后一个元素被删,队尾指针指向头结点
    delete p;
}

 三、栈和队列的应用

1.十进制转八进制问题

   思路:可运用栈的特性,将每次 N mod 8 的值压入栈中,然后 N 更新为 N / 8;最后不断从栈顶弹出元素,即为八进制数。

//-----十进制转八进制-----
void conversion(int N)
{
    InitStack(S);
    while(N)
    {
        Push(N % 8);
        N/=8;
    }
    while(!StackEmpty(S))
    {
        Pop(S,e);
        cout<<e;
    }
}

2.括号匹配问题

   思路:可运用栈的特性,将输入的字符串中的左括号压入栈中,若遇到右括号,则判断是否与栈顶的左括号匹配,若匹配,则弹出栈顶的左括号,flag=1;否则,flag=0,即不匹配,退出循环。

//-----括号匹配-----
void matching()
{
    InitStack(S);
    flag=1;
    cin>>ch;  //输入第一个字符,字符串以 # 结束
    while(ch!='#'&&flag)
    {
        switch(ch)
        {
            case '(':
            case '[':
                Push(S,ch);
                break;
            case ')':
                if(!StackEmpty(S)&&GetTop(S)=='(')
                    Pop(S,x);
                else
                    flag=0;
                break;
            case ']':
                if(!StackEmpty(S)&&GetTop(S)=='[')
                    Pop(S,x);
                else
                    flag=0;
                break;
        }
        cin>>ch;
    }
    if(StackEmpty(S)&&flag)
        return TRUE;
    else
        return FALSE;
}

3.表达式求值

  思路:建立两个栈:OPTR存运算符,OPND存操作数和运算结果;表达式以#开头和结尾;比较运算符的优先级来进行运算。

//-----表达式求值-----
char EvaluateExpression()
{
    InitStack(OPND);  //存操作数和运算结果
    InitStack(ONTR);  //存运算符
    Push(OPTR,'#');
    cin>>ch;
    while(ch!='#' || GetTop(OPTR)!='#')
    {
        if(!In(ch))
        {
            Push(OPND,ch);
            cin>>ch;  //不是运算符,存入OPND中
        }
        else  //运算符
        {
            switch (Precede(GetTop(OPTR),ch))  //比较栈顶元素和ch的优先级
            {
                case '<'
                    Push(OPTR,ch);
                    cin>>ch;  //将ch压入栈
                    break;
                case '>'
                    Pop(OPTR,theta);  //弹出运算符
                    Pop(OPND,b);
                    Pop(OPND,a);  //弹出两个操作数
                    Push(OPND.Operate(a,theta,b));  //将运算结果存入OPND中
                    break;
                case '=':
                    Pop(OPTR,x);
                    cin>>ch;
                    break;  //这时候栈顶为( 且ch为 ),括号匹配后弹出栈顶括号
            }
        }
        return GetTop(OPND);
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值