栈:
先进后出的动态结构,也就是说可以去掉的元素是最近插入的那一个
用一个数组S[1..n]实现一个至多有n个元素的栈,top[S]指向最近插入的元素,S[1]表示栈底元素,S[top[S]]表示栈顶元素,如下图所示:
以下是栈所支持的操作:
//该代码不考虑栈的溢出情况,使用int数组实现
#include <stdio.h>
#include <stdlib.h>
//假设栈所支持的元素最大个数是10个
#define MAX 10
#define TRUE 1
#define FALSE 0
//栈使用数组实现,元素的类型采用int,最大个数MAX
typedef struct Stack
{
int A[MAX];
}Stack;
//检测栈是否为空,通过指向栈顶的指针是否指向第一个元素之前来判定
int Stack_Empty(int top)
{
if(top==-1)
return TRUE;
else
return FALSE;
}
//入栈操作,需要三个参数,栈S,放入的元素x,栈顶指针top,入栈后需要修改top的值,这里传的是地址
void Stack_Push(Stack* S,int x,int *top)
{
*top=*top+1;
(*S).A[*top]=x;
}
//出栈操作,只需要将top指针减1,并返回上一个元素的值
int Stack_Pop(Stack S,int* top)
{
if(Stack_Empty(*top))
{
printf("数组为空,弹出失败\n");
return FALSE;
}
else
{
*top=*top-1;
return S.A[*top+1];
}
}
//主函数测试
int main()
{
Stack S;
int top=-1;
printf("弹出的元素为:%d\n",Stack_Pop(S,&top));
printf("栈是否为空?%d\n",Stack_Empty(top));
Stack_Push(&S,1,&top);printf("入栈的元素为:%d\n",S.A[top]);
Stack_Push(&S,2,&top);printf("入栈的元素为:%d\n",S.A[top]);
printf("弹出的元素为:%d\n",Stack_Pop(S,&top));
return 0;
}
队列:
先进先出的动态结构,好比排队等待的时候,出队的元素总是第一个,而插入的元素总是排在队尾。
用一个数组Q[1..n]实现队列,head[Q]指向队列的头,tail[Q]指向队列的尾的下一个元素,在最后一个位置要进行“卷绕”,将n个元素绕成环形,即位置1接在位置n之后。
当head[Q]=tail[Q]时队列为空,刚开始时有head[Q]=tail[Q]=1。当head[Q]=tail[Q]+1时,队列是满的。
具体如下图所示:
队列所支持的操作:
#include <stdio.h>
#include <stdlib.h>
#define MAX 10
#define TRUE 1
#define FALSE 0
//队列采用数组,最大值设定为MAX
typedef struct Queue
{
int A[MAX];
}Queue;
//入队操作,在队列最后增加一个元素,并修改队尾指针tail的值
//要注意队列采用循环形式,要判断队列尾指针是否到达末端,决定是否循环到第一个位置
void ENQUEUE(Queue* Q,int x,int* tail)
{
(*Q).A[*tail]=x;
if(*tail==MAX-1)
*tail=0;
else
*tail+=1;
}
//出队操作,返回head所指向的数据,并将head加1,同样的,判断head是否到达了队列末端
int DEQUEUE(Queue Q,int* head)
{
int x=Q.A[*head];
if(*head==MAX-1)
*head=0;
else
*head+=1;
return x;
}
//主函数测试
int main()
{
Queue Q;
int head=0;int tail=0;
ENQUEUE(&Q,1,&tail);printf("现在入队的元素:%d\n",Q.A[tail-1]);
ENQUEUE(&Q,2,&tail);printf("现在入队的元素:%d\n",Q.A[tail-1]);
printf("现在出队的元素:%d\n",DEQUEUE(Q,&head));
return 0;
}