栈和队列的应用大全

应用一:栈在括号匹配中的应用

#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
#define MaxSize 50

typedef char ElemType;


typedef struct
{
    ElemType data[MaxSize];
    int top;
} SqStack;

bool InitStack(SqStack *s)
{
    s->top=-1;//初始化栈
}


bool Push(SqStack *s,ElemType e)
{
    if(s->top==MaxSize-1)return false;
    s->data[++s->top]=e;
    return true;
}

bool Pop(SqStack *s,ElemType *e)
{
    if(s->top==-1)return false;
    *e=s->data[s->top--];
    return true;
}


void PrintStack(SqStack *s)
{
    int i=0;
    for(int i=0; i<=s->top; i++)
    {
        printf("%d-->",s->data[i]);
    }
    printf("\n");
}


//判断栈是否为空
bool  EmptyStack(SqStack *s)
{
    if(s->top==-1)return true;
    return false;
}

bool BracketsCheck(char *str)
{
    SqStack s;
    InitStack(&s);
    int i=0;
    char e;
    while(str[i]!='\0')
    {
        switch(str[i])
        {
        //左括号匹配
        case '(':
            Push(&s,'(');
            break;
        case '[':
            Push(&s,'[');
            break;
        case '{':
            Push(&s,'{');
            break;
        //右括号检测栈顶
        case')':
            Pop(&s,&e);
            if(e!='(') return false;
            break;
        case ']':
            Pop(&s,&e);
            if(e!='[')return false;
            break;
        case '}':
            Pop(&s,&e);
            if(e!='{')return false;
            break;
            default: break;
        }
        i++;
    }
    if(!EmptyStack(&s))
    {
        printf("括号不匹配\n");
        return false;
    }
    else
    {
        printf("括号匹配\n");
        return true;

    }
}



int main()
{


    char d[12];
    char *p;//p为字符数组
    printf("请输入匹配表达式\n");
    gets(d);
    p=d;
    printf("%d",BracketsCheck(p));


    return 0;
}


应用二、表达式求值

将中缀表达式,转换为后缀表达式:操作栈栈顶元素优先级**大于等于(注意等于情况)**当前操作优先级,则栈顶元素出栈,接着比较直到,栈顶元素优先级小于当前元素优先级,当前元素入操作栈
接着依次如果是数值,则压入栈,如果是op运算符号,则从栈中取出两个元素,运算后在压入栈

实现复杂,就不做实现了

应用三、栈在递归中的应用

1、创建带序号no的栈, 表示递归层数,也就是n
2、利用栈实现递归到底 如下代码

   for(int i=n; i>=2; i--) //最后两层不需要赋值
    {
        top++; //栈顶的n小,栈底的n大
        st[top].no=i;
    }

3、依次出栈,类比递归中回溯计算当前层的数值,主要利用两个变量 fv1,fv2保存之前的结果

    while(top>=0)
    {
        st[top].val=2*x*fv2-2*(st[top].no-1)*fv1; //递归表达式
        fv1=fv2; //更新fv1   Pn-2的值
        fv2=st[top].val; //更新fv2  Pn-1的值
        top--;
    }

整体代码

#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
#define MaxSize 50

typedef char ElemType;

/*

利用栈计算递归表达式

Pn(x)= 1    ,n=0;
     = 2x   ,n=1;
     = 2xPn-1(x)-2(n-1)Pn-2(x) ,n>1  
*/


double p(int n,double x)
{
    struct stack
    {
        int no;//当前n 也就是递归层数
        double val;
    } st[MaxSize];
    int top=-1;
    for(int i=n; i>=2; i--) //最后两层不需要赋值
    {
        top++; //栈顶的n小,栈底的n大
        st[top].no=i;
    }
    double fv1=1,fv2=2*x;//P0=1,P1=2*x
    while(top>=0)
    {
        st[top].val=2*x*fv2-2*(st[top].no-1)*fv1; //递归表达式
        fv1=fv2; //更新fv1   Pn-2的值
        fv2=st[top].val; //更新fv2  Pn-1的值
        top--;
    }
    if(n==0)
    {
        return fv1;
    }
    return fv2;
}


int main()
{

    printf("%lf",p(3,1));  //-4



    return 0;
}


应用三、二叉树层序遍历

#include "stdio.h"  
#include "stdlib.h"    
 
#define ERROR 0
 
typedef struct tree
{  
    char data;  
    struct tree *lchild;  
    struct tree *rchild;  
 }*Ptree; 
 
typedef Ptree ElementType;
 
struct Node{      
     ElementType Data;      
    struct Node *Next;      
};      
      
struct QNode{      
    struct Node *rear;      
    struct Node *front;      
};  
typedef struct QNode *Queue;    
 
//创建树
Ptree createTree();
 
//创建队列  
Queue CreateQueue();  
//删除队列头元素  
ElementType DeleteQ(Queue PtrQ);   
//在队尾插入元素  
void InsertQ(ElementType item,Queue PtrQ);  
//判断是否空    
int IsEmpty(Queue Q);  
 
//利用队列层次遍历
void LevelOrderTraversal(Ptree BT);
 
 
void main()  
{   
   Ptree t; 
   printf("先序创建二叉树,用空格代表虚结点:\n");
   t=createTree(); 
   printf("\n");
   printf("利用队列的层次遍历:\n");
   LevelOrderTraversal(t);
   printf("\n");
   system("pause");
}
 
 
 
//树的建立
 Ptree createTree()   
 {  
     char ch;  
     Ptree t;  
     ch=getchar();  //输入二叉树数据
     if(ch==' ')  //判断二叉树是否为空
         t=NULL;  
     else 
     {  
         t=(Ptree)malloc(sizeof(Ptree));  //二叉树的生成
         t->data=ch;  
         t->lchild=createTree();  
         t->rchild=createTree();  
     }  
     return t;  
 }  
 
 
//创建队列  
Queue CreateQueue(){  
    Queue PtrQ;    
    PtrQ=(Queue)malloc(sizeof(struct QNode));  
    struct Node *rear;  
    struct Node *front;  
    rear =(Node*)malloc(sizeof(struct Node));  
    rear=NULL;  
    front =(Node*)malloc(sizeof(struct Node));  
    front=NULL;  
    PtrQ->front=front;  
    PtrQ->rear=rear;  
    return PtrQ;  
};  
 
//删除队列头元素 
ElementType DeleteQ(Queue PtrQ){      
    struct Node *FrontCell;      
    ElementType FrontElem;      
      
    if(IsEmpty(PtrQ)){      
        printf("队列空");      
        return ERROR;      
    }    
    FrontCell=PtrQ->front;    
    if(PtrQ->front==PtrQ->rear)    
       PtrQ->front=PtrQ->rear=NULL;    
    else{    
        PtrQ->front=PtrQ->front->Next;    
    }    
      FrontElem=FrontCell->Data;    
      free(FrontCell);    
      return FrontElem;      
}      
 
//在队尾插入元素  
void InsertQ(ElementType item,Queue PtrQ){    
    struct Node *FrontCell;    
    FrontCell=(Node*)malloc(sizeof(struct Node));  
    FrontCell->Data=item;  
    FrontCell->Next=NULL;  
  
    if(IsEmpty(PtrQ)){  
        PtrQ->front=FrontCell;  
        PtrQ->rear=FrontCell;  
    }  
    else{  
        PtrQ->rear->Next=FrontCell;  
        PtrQ->rear=FrontCell;  
    }  
};     
 
//判断是否空
int IsEmpty(Queue Q){  
     return(Q->front==NULL);    
}; 
 
 
 
//利用队列层次遍历
void LevelOrderTraversal(Ptree BT)
{
	Queue Q;
	Ptree T;
	if(!BT) return;
	Q=CreateQueue();
	T=BT;
	InsertQ(T,Q);
	while(!IsEmpty(Q)){
		T=DeleteQ(Q);
		printf("%c",T->data);
		if(T->lchild) InsertQ(T->lchild,Q);
		if(T->rchild) InsertQ(T->rchild,Q);
	}
};
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值