一、栈
(一)栈的定义和基本运算
1.栈的定义
栈是一种只能在一端进行插入或删除操作的线性表,也称为后进后出表。
相关的概念包括“栈顶”、“栈底”、“空栈”、“进栈/入栈”、“出栈/退栈”等。
n个不同元素通过一个栈产生的出栈序列的个数为 。
2.基本运算
初始化栈InitStack(&s):构造一个空栈s。
销毁栈DestroyStack(&s):。释放栈s占用的存储空间。
判断栈是否为空StackEmpty(s):若栈s为空,则返回真;否则返回假。
进栈Push(&S,e):将元素e插入到栈s中作为栈顶元素。
出栈Pop(&s,&e):从栈s中退出栈顶元素,并将其值赋给e。
取栈顶元素GetTop(s,&e):返回当前的栈顶元素,并将其值赋给e。
(二)栈的顺序存储结构
1.顺序栈的存储和声明
可用下列方式来声明顺序栈的类型SqStack:
typedef struct{
ElemType data[MaxSize];
int top;
} SqStack;
栈空条件:top=-1
栈满条件:top=MaxSize-1
2.部分基本运算的实现
(1)初始化栈:采用栈指针s指向一个空栈
void InitStack(SqStack *&s){
s=(SqStack *)malloc(sizeof(SqStack));
s->top=-1;
}
(2)进栈
bool Push(SqStack *&s,ElemType e){
if(s->top==MaxSize-1)
return false;
s->top++;
s->data[s->top]=e;
return true;
}
(3)出栈
bool Pop(SqStack *&s,ElemType &e){
if(s->top==-1)
return false;
e=s->data[s->top];
s->top--;
return true;
}
3.共享栈
typedef struct{
ElemType data[MaxSize];
int top1,top2;
} DStack;
栈空条件:栈1空为top1==-1,栈2空为top2=MaxSize.
栈满条件:top1=top2-1;
进栈操作:进栈1为top1++;data[top1]=x;进栈2为top2--;data[top2]=x。
出栈操作:出栈1为x=data[top1];top1--;出栈2为x=data[top2];top2++。
(三)栈的链式存储结构
1.链栈的存储和声明
链栈中结点类型LinkStNode的声明如下:
typedef struct linknode{
ElemType data;
struct linknode *next;
} LinkStNode;
栈空条件:s->next==NULL
栈满条件:只有内存溢出才会栈满,一般不考虑
2.部分基本运算的实现
(1)初始化栈
void InitStack(LinkStNode *&s){
s=(LinkStNode *)malloc(sizeof(LinkStNode));
s->next=NULL;
}
(2)进栈
bool Push(LinkStNode *&s,ElemType e){
LinkStNode *p;
p=(LinkStNode *)malloc(sizeof(LinkStNode));
p->data=e;
p->next=s->next;
s->next=p;
return true;
}
(3)出栈
bool Pop(LinkStNode *&s,ElemType &e){
LinkStNode *p;
if(s->next==NULL)
return false;
p=s->next;
e=p->data;
s->next=p->next;
free(p);
return true;
}
(四)C++ STL 栈的实现
#include<stack> //头文件
stack<ElemType> name; //stack的定义
s.empty(); //栈空返回true 否则false
s.push(x); //将x入栈
s.pop(); //将栈顶元素出栈
s.top(); //返回栈顶元素
s.size(); //返回栈中元素的个数
二、队列
(一)队列的定义和基本运算
1.队列的定义
队列简称队,是一种仅允许在表的一端进行插入操作,而在表的另一端进行删除操作的线性表,也称为先进先出表。
相关的概念包括“队尾”、“队头/队首”、“进队/入队”、“出队/离队”等。
2.基本运算
初始化队列InitQueue(&q):构造一个空队列q。
销毁队列DestroyQueue(&q):释放队列q占用的存储空间。
判断队列是否为空QueueEmpty(q):若队列q为空,则返回真;否则返回假。.
进队列enQueue(&q,e):将元素e进队作为队尾元素。
出队列deQueue(&q,&e):从队列q中出队一个元素,并将其值赋给e。
(二)队列的顺序存储结构
1.顺序队的存储和声明
顺序队类型SqQueue声明如下:
typedef struct{
ElemType data[MaxSize];
int front,rear;
}
队空条件:q->front==q->rear
队满条件:q->rear==MaxSize-1
2.部分基本运算的实现
(1)初始化队列
void InitQueue(SqQueue *&q){
q=(SqQueue *)malloc(sizeof(SqQueue));
q->front=q->rear=0;
}
(2)进队列
bool enQueue(SqQueue *&q,ElemType e){
if(q->rear==MaxSize-1)
return false;
q->rear++;
q->data[q->rear]=e;
return true;
}
(3)出队列
bool deQueue(SqQueue *&q,ElemType &e){
if(q->front==q->rear)
return false;
q->front++;
e=q->data[q->front];
return true;
}
3.环形队列
环形队列首尾相连后,当队尾指针rear=MaxSize-1后,在前进一个位置就到达0,就可以用另一端的空位置存放队列元素,可以采用数学上的求余运算来实现:
队头指针front循环增1:front=(front+1)%MaxSize;
队尾指针rear循环增1:rear=(rear+1)%MaxSize;
(三)队列的链式存储结构
1.链队的存储和声明
链队中数据节点的类型DataNode声明如下:
typedef struct qnode{
ElemType data;
struct qnode *next;
} DataNode;
链队头结点(或链队结点)的类型LinkQuNode声明如下:
typedef struct{
DataNode *front;
DataNode *rear;
} LinkQuNode;
队空条件:q->rear==NULL(或q->front==NULL)
队满条件:不考虑
2.部分基本运算的实现
(1)初始化队列
void InitQueue(LinkQuNode *&q){
q=(LinkQuNode *)malloc(sizeof(LinkQuNode));
q->front=q->rear=NULL;
}
(2)销毁队列
void DestroyQueue(LinkQuNode *&q){
DataNode *pre=q->front,*p;
if(pre!=NULL){
p=pre->next;
while(p!=NULL){
free(pre);
pre=p;
p=p->next;
}
free(pre);
}
free(q);
}
(3)进队列
bool enQueue(LinkQuNode *&q,ElemType e){
DataNode *p;
p=(DataNode *)malloc(sizeof(DataNode));
p->data=e;
p->next=NULL;
if(q->rear==NULL)
q->front=q->rear=p;
else{
q->rear->next=p;
q->rear=p;
}
return true;
}
(4)出队列
bool deQueue(LinkQuNode *&q,ElemType &e){
DataNode *t;
if(q->rear==NULL)
return false;
t=q->front;
if(q->front==q->rear)
q->front=q->rear=NULL;
else
q->front=q->front->next;
e=t->data;
free(t);
return true;
}
(四)C++ STL 队列的实现
#include <queue> //头文件
queue<ElemType> name; //queue的定义
q.empty(); //队列为空时返回true,否则返回false
q.push(x); //入队操作,将x插入到队列
q.pop(); //出队操作,删除队头元素
q.front(); //返回队头元素
q.back(); //返回队尾元素
q.size(); //返回队列中元素的个数
三、栈和队列的应用
设计一个支持
push
,pop
,top
操作,并能在 常数时间 内检索到最小元素的栈。实现
MinStack
类:
MinStack()
初始化堆栈对象。void push(int val)
将元素val推入堆栈。void pop()
删除堆栈顶部的元素。int top()
获取堆栈顶部的元素。int getMin()
获取堆栈中的最小元素。
给你一个字符串表达式
s
,请你实现一个基本计算器来计算并返回它的值。整数除法仅保留整数部分。
你可以假设给定的表达式总是有效的。所有中间结果将在
[-231, 231 - 1]
的范围内。注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如
eval()
。提示:
1 <= s.length <= 3 * 105,s
由整数和算符('+', '-', '*', '/')
组成,中间由一些空格隔开,s
表示一个 有效表达式,表达式中的所有整数都是非负整数,且在范围[0, 231 - 1]
内,题目数据保证答案是一个 32-bit 整数
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(
push
、top
、pop
和empty
)。实现
MyStack
类:
void push(int x)
将元素 x 压入栈顶。
int pop()
移除并返回栈顶元素。
int top()
返回栈顶元素。
boolean empty()
如果栈是空的,返回true
;否则,返回false
。