数据结构-栈和队列

本文详细介绍了栈和队列的概念、逻辑结构、存储结构及其应用场景,包括顺序栈、链栈、顺序队、链队、循环队列、双端队列以及它们在表达式转换、括号匹配等问题中的应用。还探讨了共享栈和用栈模拟队列的方法,以及如何使用栈求解中缀、后缀和前缀表达式的值。
摘要由CSDN通过智能技术生成

栈和队列

定义:

只能在一端进行插入或删除操作的线性表

约束条件:

只能在一端进行插入或删除操作

一端:

可以插入或者删除元素的一端叫栈顶,另一端叫栈底

逻辑结构

先进后出

存储结构

顺序栈和链栈

顺序栈

顺序栈定义:
int stack[maxsize];
int top=-1;
元素入栈:
stack[++top]=x;
元素出栈:
x=stack[top--]
判断栈空:
if(top==-1) return 1;
判断栈满:
if(top==maxSize-1) return 1;

链栈

链栈定义:
typedef struct LNode
{
   
	int data;
	struct LNode *next;
}LNode;

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;
判断栈空:
if(head->next==NULL) return 1;
判断栈满:

内存无限大的情况下,栈就不会满

队列

定义:

队列是一种插入元素只能在一端进行,删除元素只能在另一端进行的线性表

约束条件:

插入元素只能在一端进行,删除元素只能在另一端进行

一端:

可以插入元素的一端叫队尾(Rear)

另一端

可以删除元素的一端叫队头(Front)

逻辑结构

先进先出

存储结构

顺序队和链队

顺序队

顺序队定义:
int queue[maxSize];
int front=0,rear=0;
元素入队:
rear=(rear+1)%maxSize;
queue[rear]=x;
元素出队:
front=(front+1)%maxSize;
x=queue[front];
判断队空:
if(front==rear)return 1;
判断队满:
if(front==(rear+1)%maxSize)return 1;

链队

链队定义:
typedef struct LNode
{
   
	int data;
	struct LNode *next;
}LNode;

LNode *head=(LNode*)malloc(sizeof(LNode));
head->next=NULL;
LNode *front=head->next;
LNode *rear=head;
LNode *s=NULL;
元素入队:
s=(LNode*)malloc(sizeof(LNode*));
s->next=NUll;
s->data='A';
rear->next=s;
rear=rear->next;
元素出队:
front=head->next;
x=front->data;
head->next=front->next;
free(front);
判断队空:
if(front==rear) return 1;
判断栈满:

内存无限大的情况下,栈就不会满

输出序列

1.例如:
入栈序列:1,2,3,4,5,6
出栈序列:3,5,6,4,2,1
求解:
该栈容量为多少?
解答:
因为null->123->12->1245->124->1246->124->null
所以该栈容量为4
此外:
因为入栈序列最后一个位置为6
所以出栈序列6及其后面的数降序排列
即出栈序列中6及其后面的数挨个出栈即可
2.例如:
入栈序列:1、2、…、n
出栈序列:P1、P2、…、Pn
(1)若P1=n,则?
解答:
出栈序列为:n、n-1、…、1
(2)若Pi=n(1<i<n),则?
解答:
根据1的结论得出出栈顺序为:
Pi->Pi+1->…->Pn
也即出栈序列中Pi后面的数为降序排列:
Pi>Pi+1>…>Pn
(3)若i<j<k,则,Pi、Pj、Pk的大小关系如何?
解答:
由题意得出栈序列为:
P1、…、Pi、…、Pj、Pk…、…、Pn
枚举法(对Pi、Pj、Pk的入栈顺序进行全排列,6种可能):
1.Pi、Pj、Pk
2.Pi、Pk、Pj
3.Pj、Pk、Pi
4.Pj、Pi、Pk
5.Pk、Pi、Pj
6.Pk、Pj、Pi
分析:
1.入栈Pi出栈Pi,入栈Pj出栈Pj,入栈Pk出栈Pk
2.入栈Pi出栈Pi,入栈Pk入栈Pj,出栈Pj出栈Pk
3.入栈Pj入栈Pk入栈Pi,出栈Pi出栈Pk出栈Pj
4.入栈Pj入栈Pi出栈Pi出栈Pj,入栈Pk出栈Pk
5.入栈Pk入栈Pi出栈Pi,入栈Pj出栈Pj出栈Pk
6.入栈Pk入栈Pj入栈Pi,出栈Pi出栈Pj出栈Pk
结论:
通过分析得出当且仅当入栈顺序为枚举第3种也即
入栈顺序为Pj->Pk->Pi时,出栈条件不成立
又因为入栈顺序为升序
所以Pj<Pk<Pi不成立,其余成立

表达式转换

前缀式:+ab
中缀式:a+b
后缀式:ab+
中缀式->前缀式:

原理:
1.把a,b和a+b看做三个表达式并加上括号:
((a)+(b))
2.把+提到对应括号前面并扔掉括号:
+ab
例如:
中缀式(a+b)*c+d-(e+g)*h->前缀式
步骤:

(1)((a+b)*c)+d-((e+g)*h)
(2)(((a+b)*c)+d)-((e+g)*h)
(3)((((a+b)*c)+d)-((e+g)*h))
(4)-(+(*(+(ab)c)d)*(+(eg)h))
(5)-+*+abcd*+egh

代码:

```cpp
void infixToPreFix(char infix[],int len,char s2[],int &top2)
{
   
	char s1[maxSize];int top=-1;
	int i=len-1;
	while(i!=-1)
	{
   
		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
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值