03-栈和队列

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;

循环队列的配置问题

正常配置

先入队元素再移动指针,先移动指针再出队元素

image-20210930171216799image-20210930171244548

image-20210930171552969
非正常配置-1

先移动指针再入队元素,先出队再移动指针

image-20210930171922245 image-20210930172028560 image-20210930172145695
非正常配置-2
image-20210930172255633 image-20210930172312726 image-20210930172405332 image-20210930172555861

栈的扩展

共享栈
image-20210930174223431
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+

转换方法
中缀表达式转前缀表达式

image-20211101231845558image-20211101231927418

image-20211101232021228image-20211101232035299

中缀转后缀
image-20211107212557880 image-20211107213144187
后缀转中缀
image-20211107213613651
后缀转前缀
image-20211107213732844

用栈实现表达式转换

中缀转后缀

//从右往左扫描
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];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Black_Me_Bo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值