数据结构中当然少不了栈和队列,不过在深入理解了链表的各种操作之后栈或者队列就比较简答了,我的理解是栈和队列只是逻辑上的数据结构,概念比较简单,但是应用确很多,而栈和队列都对数据有频繁的添加和删除操作,所以一般比较少用动态分配内存的方式(动态分配内存需要额外的开销),所以一般直接采用数组和指针的形式(不一定是指针,只要能进行逻辑上的操作即可,后面默认为指针),栈比较简单,只需要设置一个top指针即可,一般的队列也是比较简单的,设置首尾指针,但是我们知道数组是静态分配数据,而首尾指针一般情况下是只能往一个方向移动,所以很容易造成一种现象,就是数组的尾指针到了数组的最后(默认为尾指针为数组的起点Array[0],头指为数组的后面),而尾指针前面的内存空间并没有保存数据,就是俗称的“假上溢”,所以采用循环数组的形式解决内存空间的利用率问题,下面的代码就是循环队列的各种操作的实现
#include <stdio.h>
#include <assert.h>
//typedef void * ElemType;
typedef int ElemType;
#define MAX 5 //设置一个长度为10 的循环队列,方便后面测试
ElemType e[MAX];
int front =0;
int rear =0;
//int front=0;
//int rear=1;
//队列的一般的几种运算
//判空
bool IsEmpty() //满和空的时候不一样
{
// if((rear-front%MAX)==1)
if(rear == front)
return true;
return false;
}
bool IsFull()
{
//if((front-rear%MAX)==1)
if((rear+1)%MAX==front) //这个表示队列为满
return true;
return false ;
}
//首先要看能够插入
bool Push(ElemType elem)
{
if(!IsFull())
{
e[rear]=elem;
rear = (rear+1)%MAX;
return true;
}
return false;
}
//如果两个之间空格一个1,则首元素是front-1
ElemType Front()
{
assert(!IsEmpty());
// if(front == 0)
// return e[];
//将插入的方式改变即可
// return e[(front];
return e[front];
}
bool Pop()
{
if(!IsEmpty())
{
front =(front+1)%MAX;
return true;
}
return false;
}
int main()
{
/*这个只是简单的测试,通过调式可以看到数据的变化情况*/
Push(1);
printf("%d\n",Front());
Push(2);
Pop();
Push(3);
Push(4);
Push(5);
Push(6);
printf("%d\n",Front());
// Push(5);
return 0;
}
需要注意的地方就是队列可以头进尾出也可以尾进头出,根据自己设置的指针的名称,逻辑上是相同的,这里头尾指针都是从〇开始,从rear进,从front出,判断队列空为rear = front,判断队列满为(rear+1)%MAX = front。其他的操作就基本上和一般的队列相同。