这是我第二篇关于数据结构的笔记。我觉得循环数组实现队列的一些值得注意的地方是:
1、队列是由入队和出队的操作的,每一次出队,指向数组的“头指针”Front都会向后移动一位,这时就会有大量的空间空余,因而可以通过循环数组来实现空间的有效利用。循环数组是什么意思呢,就是当队列的“尾指针”Rear的大小超过队列的最后一位,那么进行判断这个队列是否为满,如果这个队列没满,就可以将Rear移动到数组的最前面,形成一个循环。所以这里的循环数组是把原来的数组看成一个圆;
2、我的算法是模仿《数据结构与算法分析》的,里面采用了size来监测队列是否为空或者为满。而有许多其他形式的算法并未采用该种算法,而是采用了rear=front-1的形式来判断队列是否为空;
3、对于队列而言,我觉得最重要的一点就是判空和判满;
#include<stdio.h>
#include<stdlib.h>
struct Queues;
typedef struct Queues* Queue;
typedef struct Queues queue;
typedef int Elementtype;
int isEmpty(Queue Q);/* 判断队列是否为空 */
int isFull(Queue Q);/* 判断队列是否满 */
Queue CreateQueue(int MaxElements);/* 创建一个队列 */
void EnQueue(Queue Q,Elementtype x);/* 往队列里填入元素 */
void DeQueue(Queue Q);/* 弹出元素 */
void Print(Queue Q);/* 将队列元素输出 */
struct Queues{
int Capacity;/* 队列最大容量 */
int Front;/* 队头 */
int Rear;/* 队尾 */
int Size;/* 队列当前元素数量 */
Elementtype* Array;/* (循环数组)用于存储数据 */
};
int main(void)
{
Queue Q;
Q = CreateQueue(10);
EnQueue(Q,5);
EnQueue(Q,3);
EnQueue(Q,4);
DeQueue(Q);
Print(Q);
getchar();
return 0;
}
/* 创建一个新的队列 */
Queue CreateQueue(int MaxElements)
{
Queue Q;
Q = (Queue)malloc(sizeof(queue));
Q->Array = (Elementtype*)malloc(sizeof(Elementtype)*MaxElements);
if(Q->Array == NULL)
printf("segment error");
else{
Q->Front = 0;
Q->Rear = 0;
Q->Capacity = MaxElements;
Q->Size = 0;
}
return Q;
}
/* 往队列里填入 */
void EnQueue(Queue Q,Elementtype x)
{
if(isFull(Q))
printf("the Queue is full");
else{
Q->Rear = (++Q->Rear)%Q->Capacity;/* 队尾后移 */
Q->Array[Q->Rear] = x; /* 对队尾进行赋值 */
Q->Size++;
}
}
/* 出队 */
void DeQueue(Queue Q)
{
if(isEmpty(Q))
printf("the queue is empty");
else{
Q->Front = ++Q->Front % Q->Capacity;
Q->Size--;
}
}
/* 判断该队列是否为空 */
int isEmpty(Queue Q)
{
return Q->Size == 0;
}
/* 判断该队列是否为满 */
int isFull(Queue Q)
{
return Q->Size == Q->Capacity;
}
/* 打印队列 */
void Print(Queue Q)
{
int i;
if(isEmpty(Q))
printf("the queue is empty");
for(i = Q->Front;i <= Q->Size;i++)
{
if(i >= Q->Capacity)
i = i%Q->Capacity;
printf("%d ",Q->Array[i]);
}
}