栈和队列
栈
- 定义:栈是一种只能在一端进行插入或删除操作的线性表。
1.允许进行插入、删除操作的一端称为栈顶
2.表的另一端称为栈底
3.当栈中没有数据元素时,称为空栈 4.栈的插入操作通常称为进栈
5.栈的删除操作通常称为退栈
- 栈的主要特点:元素后进先出
- 栈的几种基本运算:
InitStack(&s):初始化栈。构造一个空栈s
DestroyStack(&s):销毁栈。释放s占用的存储空间。
StackEmpty(s):判断栈是否为空;若栈s为空,则返货真;否则返回假
Push(&S,e):进栈。将元素e插入到栈顶
Pop(&s,&e):出栈。从栈s中退出栈顶元素,并将其赋值给e
GetTop(s,&e):取栈顶元素。返回当前的栈顶元素,并将其值赋给e
顺序栈:
//定义
typedef struct{
ElemType data[MaxSize];
int top; //栈顶指针
}SqStack;
//初始化
void InitStack(){
s = (SqStack*)malloc(sizeof(SqStack));
s->top = -1;
}
//销毁栈
void DestroyStack(SqStack* &s){
free(s);
}
//判断栈是否为空栈
bool StackEmpty(SqStack* s){
return (s->top == -1);
}
//进栈
bool Push(SqStack* &s,ElemType e){
if(s->top == MaxSize-1)
return false;
s->top++;
s->data[s->top] = e;
return true;
}
//出栈
bool Pop(SqStack* &s,ElemType& e){
if(s->top == -1)
return false;
e = s->data[s->top];
s->top--;
return true;
}
//取栈顶元素
bool GetTop(SqStack* s,ElemType& e){
if(s->top == -1)
return false;
e = s->data[s->top];
return true;
}
链栈:
链栈的4要素
- 栈空条件:s->next=NULL
- 栈满条件:不考虑
- 进栈操作:将包含e的节点插入到头节点之后
- 退栈操作:取出头节点之后节点的元素并删除之
typedef struct linknode{
ElemType data;
struct linknode* next;
}LiStack;
//初始化栈
void initStack(LiStack* &s){
s = (LiStack*)malloc(sizeof(LiStack));
s->next = NULL;
}
//销毁栈
void DestroyStack(LiStack* &s){
LiStack* p = s, *q = s->next;
while(q != NULL){
free(p);
p = q;
q = p->next;
}
free(p);
}
//进栈
void Push(LiStack* &s,ElemType e){
LiStack* p = NULL;
p = (LiStack*)malloc(sizeof(LiStack));
p->data = e;
p->next = s->next;
s->next = p;
}
//出栈
void Pop(LiStack* &s,ElemType e){
LiStack* p = NULL;
if(s->next == NULL)
return false;
p = s->next;
e = p->data;
s->next = p->next;
free(p);
}
//取栈顶元素
bool GetTop(LiStack* s,ElemType& e){
if(s->next == NULL)
return false;
e = s->next->data;
return true;
}
- 栈的应用
当判断一组数据是不是对称时可以使用栈来判断,让数据依次进栈,产生的出栈序列与原数据序列相同
bool symmetry(ElemType str[]){
int i; ElemType e; SqStack* st;//初始化栈
for(i=0;str[i]!='\0';i++)//将串所有元素进栈
Push(st,str[i]);//元素进栈
for(i=0;str[i]!='\0';i++){
Pop(st,e);
if(str[i]!=e){
DestroyStack(st);
return false;
}
}
DestroyStack(st);
return true;
}
队列
- 定义:队列简称队,它是一种运算受限的线性表。
队列只能选取一个端点进行插入操作,另一个端点进行删除操作
执行插入操作的称为队尾(rear)
执行删除的一端称为队头(front)
向队列中插入一个元素称为进队,新元素进队成为新的队尾
从队列中删除元素称为出队,元素出队后,后继元素成为新的队首
- 队列的基本操作
1.初始化队列,构造一个空队列
2.销毁队列。释放队列q占用的存储空间
3.判断队列是否为空。若队列为空,则返回真;否则返回假
4.进队列。将元素e进队作为队尾元素
5.出队列。从队列中出队一个元素,并将其赋值给e
- 顺序队
/*
1.队空条件:front=rear
2.队满条件:(rear+1)%MaxSize=front
3.元素e进队:rear=(rear+1)%MaxSize
4.元素e出队:front=(front+1)%MaxSize
5.元素个数:count=(rear-front+MaxSize)%MaxSize
*/
//定义
typedef struct{
ElemType data[MaxSize];
int front;
int rear;
}SqQueue;
//初始化
void initQueue(SqQueue* &q){
q = (SqQueue*)malloc(sizeof(SqQueue));
q->front = -1;
q->rear = -1;
}
//销毁
void DestroyQueue(SqQueue*&q){
free(q);
}
//判空
void isEmpty(SqQueue*&q){
if(q->front == q->rear)
return false;
return true;
}
//进队
bool enQueue(SqQueue*&q,ElemType &e){
if(q->rear == MaxSize-1)
return false;
q->rear = (q->rear+1) % MaxSize;
q->data[q->rear] = e;
return true;
}
//出队
bool deQueue(SqQueue*&q,ElemType&e){
if(q->front == q->rear)
return false;
e = q->data[front];
q->front = (front+1)%MaxSize;
return true;
}
链式队列:
/*
1.队空条件:front=rear=NULL
2.对满条件:不考虑
3.进队操作:将包含e的节点插入到链表尾部
4.出队操作:删除单链表首数据节点
*/
//定义
typedef struct qnode{
ElemType data;
struct qnode* next;
}QNode;
typedef struct{
QNode* front;
QNode* rear;
}LiQueue;
//初始化队列
void InitQueue(LiQueue*&q)
{
q=(LiQueue*)malloc(sizeof(LiQueue));
memset(q,0,sizeof(LiQueue));
}
//销毁队列
void DestrpyQueue(LiQueue*&q)
{
QNode* p = q->front, *r;
if(p != NULL){
r = p->next;
while(r != NULL){
free(p);
p = r;
r = p->next;
}
}
free(p);
free(q);
}
//判断队列是否为空
bool isEmpty(LiQueue* q)
{
return (q->rear==NULL);
}
//进队
void enQueue(LiQueue*&q,ElemType e)
{
QNode* p;
p = (QNode*)malloc(sizeof(QNode));
p->data = e;
p->next = NULL;
if(q->rear == NULL){//若链队为空,新节点是队首节点又是队尾节点
q->front = p;
q->rear = p;
}else{
q->rear->next = p;//将*p节点链到队尾,并将rear指向它
q->rear = p;
}
}
//出队
bool deQueue(LiQueue*&q,ElemType& e)
{
QNode* t;
if(q->rear == NULL) return false;//队列为空
t = q->front; //t指向第一个数据节点
if(q->front == q->rear){ //队列中只有一个节点时
q->front = NULL;
q->rear = NULL;
}else{
q->front = q->front->next;
}
e = t->data;
free(t);
return true;
}