栈
栈的定义:栈(stack)是限定仅在表尾进行插入和删除操作的线性表。
我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈有称为先进后出的线性表,简称LIFO结构。
栈的插入操作,叫做进栈,也称压栈、入栈。
栈的删除操作,叫做出栈,也有的叫做弹栈。
一、栈的顺序存储
用数组实现出栈,进栈:
int a[10100];//定义一个一维数组来当作栈
int push=0,pop=0;
int n;
for(int i=0;i<m;i++)
{
scanf("%d",&n);
a[push++]=n;//进栈操作
}
int b[101000];
for(int i=0;i<n;i++)
{
b[i]=a[pop++];//出栈操作
}
用结构体和指针来实现进栈,出栈:
//进栈
int maxsize=10;
typedef struct stack//用结构体定义栈的结构
{
int data[maxsize];
int top;//用于栈顶指针
}Stack;
//进栈操作push
int Push(Stack *s,int e)
{
if(s->top==maxsize-1)//此时栈是满的
return Flase;
s->top++;//栈顶指针增加一
s->data[s->top]=e;//将新插入的元素赋值给栈顶空间
return True;
}
//出栈
int Pop(Stack *s,int *e)
{
if(s->top==-1)//此时栈为空栈
return False;
*e=s->data[s->top];将要删除的栈顶元素的值赋给指针e
s->top--;//栈顶指针减一
return True;
}
二、栈的链式存储
构建栈:
typedef struct stack
{
int data;
struct stack *next;
}Stack,*Link;
typedef struct linkstack
{
Link top;
int cnt;
}Linkstack;
进栈操作
int Push(Linkstack *s,int e)
{
Link p=(Link)malloc(sizeof(stack));
s->data=e;
s->next=S->top;//把当前栈顶元素赋给新结点的直接后继
S->top=s;//将新结点s赋值给栈顶指针
S->cnt++;
return True;
}
出栈操作
int Pop(Linkstack *S,int *e)
{
Link p;
if(S->count==-1)//如果栈为空,则返回False
return False;
*e=S->top->data;
p=S->top;//将栈顶的值赋给p
S->top=S->top->next;//使栈顶指针下移一位,指向后一结点
free(p);//释放结点p
S->count--;
return True;
}
队列
队列的定义:队列是具有一定操作约束的线性表,是只允许在一段进行插入操作,而在另一端进行删除操作的线性表。
队列是一种先进先出的线性表,简称FIFO。允许插入的一短称为队尾,允许删除的一端称为队头。
数据插入:入队列(AddQ);
数据删除:出队列(DeleteQ);
先进先出:FIFO;
数据对象集:一个有0个或多个元素的有穷线性表。
操作集:长度为MaxSize的队列Q;
操作:生成长度为MaxSize的空队列Q;
判断队列Q 是否已满;
将数据元素item插入队列Q中;
判断队列Q 是否为空;
将队头数据元素从队列中删除并返回;
队列的顺序存储:队列的顺序存储结构通常有一个一维数组和一个记录队列头元素位置的变量front以及一个记录队列尾元素位置的变量rear组成:
当你增加一个元素时,rear+1;
当你删除一个元素时,front+1;(队列为空时,front=-1)
用结构体定义队列的结构
#define MaxSize//储存数据元素的最大个数
struct QNode
{
int Data[MaxSize];
int rear;
int front;
};
循环队列: 队列头尾相接的顺序储存结构;
循环队列的顺序存储结构:
typedef struct
{
int data[MaxSize];
int front;
int rear;
}CQueue;
循环队列的初始化
int ChuQueue(CQueue *Q)
{
Q->front=0;
Q->rear=0;
return OK;
}
循环队列的入队列操作以及出队列操作要判断队列是否满了(入队列)或队列是否为空(出对列),然后入队列时rear向后移一位,出队列front向后移一位;
循环队列可能会出现数组溢出的问题,所以,现在来看看队列的链式存储结构:
队列的链式存储结构:
队列的链式存储结构,其实就是线性表的单链表,只不过它是只能尾进头出而已,我们把它简称链队列。
为了操作方便我们将队头指针指向链队列的头结点,队尾指针指向终端节点:
空队列时,front和rear都指向头结点:
链队列的结构:
//结点结构
typedef struct QNode
{
int data;
struct QNode *next;
}QNode,*Queue;
//队列的链表结构
typedef struct
{
Queue front;//队头指针
Queue rear;//队尾指针
}LinkQueue;
链队列的入队列出队列操作,结合单链表的操作同时要注意front指针和rear指针的移动。