03-栈和队列
栈
链栈
LNode *head = (LNode*)malloc(sizeof(LNode));
head->next = NULL;
LNode *top = NULL;
//元素入栈
top = (LNode*)malloc(sizeof(LNode));
top->next = NULL;
top->data = 'A';
top->next = head->next;
head->next = top;
//元素出栈
x = top->data;
head->next = top->next;
free(top);
top = head->next;
队列
链队
typedef struct{
LNode *front;
LNode *rear;
}queue;
输出序列-考点
由出栈序列判断容量
1.入栈序列:1 2 3 4 5 6 出栈序列:3 4 2 1 6 5
答:栈容量至少是3
2.入栈序列:1 2 3 4 5 6 入栈后得到出栈序列:3 4 2 1 6 5 则出栈序列:5 6 1 2 4 3
答:不存在
3.入栈序列:1 2 3 4 5 6 入队后得到出队序列:3 4 2 1 6 5 则出栈序列:3 4 2 1 6 5
答:栈容量至少是3
4.入栈:1 2 3 … n 出栈:p1p2 p3 … pn
4.1 若p1 = n 则pi = n-i+1;
4.2 若 pi = n(1<i<n) 则pi>pi+1>…>pn
4.3 若i<j<k,则pi,pj,pk的大小关系为若入栈1 2 3则必无出栈3 1 2!
卡特兰数:
Cn=(2n!)/[(n+1!)n!] n个数按照某种顺序入栈,并且可在任意时刻出栈,不同出栈序列的个数为Cn;
循环队列的配置问题
正常配置
先入队元素再移动指针,先移动指针再出队元素
非正常配置-1
先移动指针再入队元素,先出队再移动指针
非正常配置-2
栈的扩展
共享栈
int stack[maxSize];
int top[2] = {-1,maxSize};
/* top[0] == -1为真则s1空,top[1] == maxSize为真则s2空
s1入栈:stack[++top[0]] = x;
s2入栈:stack[--top[1]] = x;
top[0]+1 == top[1]为真,栈满
*/
用栈模拟队列
用两个栈s1,s2来模拟队列
入队规则:
*若s1未满,则元素全入s1;
*若s1满,s2空,则将s1中元素全部出栈并入s2,腾出位置后再入s1。
出队规则:
*若s2不空,则从s2中直接出栈;
*若s2空,则将s1中元素全部出栈并入s2,然后从s2中出栈;
队满:
s1满且s2不空,则不能继续入队,即为队满状态;
队空:
s1空且s2空,则队空;
括号匹配
int isMatched(char left,char right){
if(left == '(' && right ==')')
return 1;
else if(left == '[' && right ==']')
return 1;
else if(left == '{' && right =='}')
return 1;
else
return 0;
}
//exp[]为括号表达式
int isParenthesesBalanced(char exp[]){
char s[maxSize];
int top =-1;
for(int i=0;exp[i]!='\0';++i){
if(exp[i] == '(' || exp[i] == '[' || exp[i] == '{')
s[++top] = exp[i];
if(exp[i] == ')' || exp[i] == ']' || exp[i] == '}')
{
if(top == -1) return 0;
char left = s[top--];
if(isMatched(left,exp[i]) == 0) return 0;
}
}
if(top > -1) return 0;
return 1;
}
表达式转换
各种表达式之间的转换
三种表达式
中缀表达式:a+b 前缀表达式:+ab 后缀表达式:ab+
转换方法
中缀表达式转前缀表达式
中缀转后缀
后缀转中缀
后缀转前缀
用栈实现表达式转换
中缀转后缀
//从右往左扫描
void infixToPostFix(char infix[],char s2[],int &top2){
char s1[maxSize]; int top1 =-1;
int i=0;
while(infix[i]!='\0'){
if('0'<=infix[i] && infix[i]<='9'){ //是否是数字,是数字直接入结果栈
s2[++top2]=infix[i];
++i;
}else if(infix[i]=='('){ //是否是左括号,是则入辅助栈
s1[++top1]='(';
++i;
}else if(infix[i]=='+'||infix[i]=='-'||infix[i]=='*'||infix[i]=='/'){//
if(top==-1||s1[top1]='('||getPriority(infix[i])>getPriority(s1[top1])){
//如果辅助栈为空或为左括号或当前运算符优先级大于辅助栈顶元素运算符的优先级,则扫描到的运算符入辅助栈,栈顶指针后移
s1[++top1]=infix[i];
++i;
}else{
s2[++top2]=s1[top1--];
}
}else if(infix[i]==')'){
while(s1[top1]!='('){
s2[++top2]=s1[top1--];
}
--top1;
++i;
}
}
//将辅助栈中剩余元素全部压入结果栈中
while(top!=-1){
s2[++top2]=s1[++top1--];
}
}
中缀转前缀
//从左往右扫描
void infixToPreFix(char infix[],int len,char s2[],int &top2){
char s1[maxSize]; int top1 =-1;
int i=len -1;
while(i>0){
if('0'<=infix[i] && infix[i]<='9'){ //是否是数字,是数字直接入结果栈
s2[++top2]=infix[i];
--i;
}else if(infix[i]==')'){ //是否是左括号,是则入辅助栈
s1[++top1]=')';
--i;
}else if(infix[i]=='+'||infix[i]=='-'||infix[i]=='*'||infix[i]=='/'){//
if(top==-1||s1[top1]=')'||getPriority(infix[i])>=getPriority(s1[top1])){
//如果辅助栈为空或为左括号或当前运算符优先级大于辅助栈顶元素运算符的优先级,则扫描到的运算符入辅助栈,栈顶指针后移
s1[++top1]=infix[i];
--i;
}else{
s2[++top2]=s1[top1--];
}
}else if(infix[i]=='('){
while(s1[top1]!=')'){
s2[++top2]=s1[top1--];
}
--top1;
--i;
}
}
//将辅助栈中剩余元素全部压入结果栈中
while(top!=-1){
s2[++top2]=s1[++top1--];
}
}
用栈实现表达式的计算
求中缀表达式的值
int getPriority(char op){
if(op=='+' || op=='-')
return 0;
else
return 1;
}
int calSub(float opand1,char op,float opand2,float &result){
if(op=='+') retsult = opand1+opand2;
if(op=='-') retsult = opand1-opand2;
if(op=='*') retsult = opand1*opand2;
if(op=='/'){
if(fabs(opand2)<MIN){ //fabs()求绝对值的函数
return 0;
}else{
result=opand1/opand2;
}
}
return 1;
}
int calStackTopTwo(float s1[],int &top1,char s2[],int &top2){
float opnd1,opnd2,result;
char op;
int flag;
opnd2=s1[top1--];
opnd1=s1[top1--];
op=s2[top2--];
flag=calSub(opnd1,op,opnd2,result);
if(flag==0){
std::cout<<“ERROR”<<std::endl;
}
s1[++top1]=result;
return flag;
}
float calInfix(char exp[]){
float s1[maxSize]; int top1=-1;
char s2[maxSize]; int top2=-1;
int i=0;
while(exp[i]!='\0'){
if('0'<=exp[i]&&exp[i]<='9'){
s1[++top1]==exp[i]-'0';
++i;
}else if(exp[i]=='('){
s2[++top2]='(';
++i;
}else if(exp[i]=='+'||exp[i]=='-'||exp[i]=='*'||exp[i]=='/'){
if(top2==-1||s2[top2]=='('||getPriority(exp[i])>getPriority(s2[top2])){
s2[++top2]=exp[i];
++i;
}else{
int flag=calStackTopTwo(s1,top1,s2,top2);
if(flag==0) return 0;
}
}else if(exp[i]==')'){
while(s2[top2]!='('){
int flag=calStackTopTwo(s1,top1,s2,top2);
if(flag==0) return 0;
}
--top2;
++i;
}
}
while(top!=-1){
int flag=calStackTopTwo(s1,top1,s2,top2);
if(flag==0) return 0;
}
return s1[top1];
}
求后缀表达式的值
float calPostFix(char exp[]){
float s[maxSize]; int top =-1;
for(int i=0;exp[i]!='\0';++i){
if('0'<=exp[i]&&exp[i]<='9'){
s[++top]=exp[i]-'0';
}else{
float opnd1,opnd2,result;
char op;
int flag;
opnd2=s[top--];
opnd1=s[top--];
op=exp[i];
flag =calSub(opnd1,op,opnd2,result);
if(flag==0){
std::cout<<“ERROR”<<std::endl;
return 0;
}
s[++top]=result;
}
}
return s[top];
}
求前缀表达式的值
float calPretFix(char exp[]){
float s[maxSize]; int top =-1;
for(int i=len-1;i>=0;--i){
if('0'<=exp[i]&&exp[i]<='9'){
s[++top]=exp[i]-'0';
}else{
float opnd1,opnd2,result;
char op;
int flag;
opnd1=s[top--];
opnd2=s[top--];
op=exp[i];
flag =calSub(opnd1,op,opnd2,result);
if(flag==0){
std::cout<<“ERROR”<<std::endl;
return 0;
}
s[++top]=result;
}
}
return s[top];
}