栈和队列
1、设计算法将中缀表达式转换为后缀表达式,并对后缀表达式求值。
2、请利用两个栈S1和S2来模拟一个队列。已知栈的三个操作定义如下:PUSH(ST,x),元素x入栈ST,POP(ST,X),ST栈顶元素出栈并赋给变量x;Sempty(ST),判断ST栈是否为空。那么利用栈的操作来实现该队列的三个操作:EnQueue,插入一个元素入队;DeQueue,删除一个元素出队;QueueEmpty,判队列为空。
3、假设一带头节点的循环链表表示队列,并且只设一个指针指向队尾结点,但不舍头指针,请写出相应的入队和出队算法。
1:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
char s[100];
int i=0;
typedef struct node
{
char data;
struct node *next;
} Node,*LinkList;
LinkList Createzhan1()//创建符号栈
{
LinkList top;
top=NULL;
return top;
}
LinkList push(LinkList s,char x)//栈中插入元素
{
LinkList q,top=s;
q=(LinkList)malloc(sizeof(Node));
if(!q) return 0;
q->data=x;
q->next=top;
top=q;
return top;
}
LinkList pop(LinkList s,char &e)//删除栈顶元素
{
e=s->data;
LinkList p=s;
s=s->next;
free(p);
return s;
}
char GetTop(LinkList s)//取得栈顶元素
{
return s->data;
}
int precede(char op1, char op2)
{
if(op1 == ')'&& op2 == '(')
return 2;
else if (op1 == '('||op2 == '(' || op2 == '#')
return 0;
else if(op1 == ')')
return 1;
else if (op1 == '+' || op1 == '-')
{
return 1;
}
else if (op1 == '*' || op1 == '/')
{
if (op2 == '+' || op2 == '-')
return 0;
else
return 1;
}
}
int isInt(char a)//判断是不是整数
{
if(a>='0'&&a<='9')
return 1;
else return 0;
}
char to(LinkList optr)//中缀表达式变后缀
{
optr=push(optr,'#');//’#’置于栈底,级别最低
char c=getchar();//读入表达式,以’#’结束
while(c!='#'||GetTop(optr)!='#')
{
if(isInt(c))//若读入字符c是数字字符,放入数组
{
s[i++]=c;
c=getchar();
}
else
{
if(c==')')//去括号
{
while(GetTop(optr)!='(')
{
optr=pop(optr,s[i++]);
}
char x;
optr=pop(optr,x);
c=getchar();
}
else if(!precede(c,GetTop(optr)))//c级别高,入栈
{
optr=push(optr,c);
c=getchar();
}
else if(precede(c,GetTop(optr)))
{
optr=pop(optr,s[i++]);
}
}
}
}
char sum(char a,char t,char b)
{
int c=a-'0';
int d=b-'0';
if(t=='+')
{
a=c+d+'0';
return a;
}
else if(t=='-')
{
a=c-d+'0';
return a;
}
else if(t=='*')
{
a=c*d+'0';
return a;
}
else if(t=='/')
{
a=c/d+'0';
return a;
}
}
char tosum(LinkList optr)//后缀表达式的计算
{
i=0;
char c=s[i++];
while(c!='#')
{
if(isInt(c))
{
optr=push(optr,c);
c=s[i++];
}
else
{
char a,b;
optr=pop(optr,b);
optr=pop(optr,a);
optr=push(optr,sum(a,c,b));//进行相应运算,结果入栈
c=s[i++];
}
}
return GetTop(optr);
}
int main()
{
LinkList top1;
top1=Createzhan1();
to(top1);
s[i]='#';
cout<<tosum(top1)-'0'<<endl;
return 0;
}
2:
栈的特点是后进先出,队列的特点是先进先出。所以,用两个栈s1和s2模拟一个队列时,s1作输入栈,逐个元素压栈,以此模拟队列元素的入队。当 需要出队时,将栈s1退栈并逐个压入栈s2中,s1中最先入栈的元素,在s2中处于栈顶。s2退栈,相当于队列的出队,实现了先进先出。显然,只有栈s2 为空且s1也为空,才算是队列空。
int QueueEmpty(LinkList S1,LinkList S2)
{
if(Sempty(S1)||Sempty(S2))
return 0;
else
return 1;
}
void EnQueue(LinkList &S1,int e)
{
push(S1,e);
}
void deQueue(LinkList &S1,LinkList &S2,int &e)
{
if(QueueEmpty(S1,S2))
cout<<"队列为空"<<endl;
else
{
int x;
while(!Sempty(S1))
{
pop(S1,x);
push(S2,x);
}
pop(S2,e);
while(!Sempty(S2))
{
pop(S2,x);
push(S1,x);
}
}
}
3:
void InitQueue(Queue &Q)
{
Q=(Node*)malloc(sizeof(Node));
Q->next=Q;
}
void EnQueue(Queue &Q,int e)
{
p=(Node*)malloc(sizeof(Node));
p->data=e;
p->next=Q->next;
Q->next=p;
Q=p;
}
void DeQueue(Queue &Q,int &e)//
{
p=Q->next->next;
e=p->data;
Q->next->next=p->next;
free(p);
}