队列的实现
1、循环队列(顺序存储)
1.1、循环队列的基本操作
#include <stdlib.h>
#include <stdio.h>
#define MaxSize 10
typedef struct {
//静态数组,存放数据
int data[MaxSize];
int front;
int rear;
}SqQueue;
//初始化循环队列
void InitSqQueue(SqQueue *Q)
{
Q->front=0;
Q->rear=0;
}
//判断队列是否已满
int SqQueueFull(SqQueue *Q)
{
if(Q->rear+1==Q->front)
{
return 1;
}
else
{
return 0;
}
}
//判断是否为空队列
int SqQueueEmpty(SqQueue *Q)
{
if(Q->front==Q->rear)
{
return 1;
}
else
{
return 0;
}
}
//入队
int EnQueue(SqQueue *Q,int e)
{
//判断队列是否已满
int flag= SqQueueFull(Q);
if(flag==1)
{
printf("队列已满,入队失败!\n");
return 0;
}
//将数据元素插入队尾指针所指处,并将队尾指针向后移1位
Q->data[Q->rear]=e;
Q->rear=(Q->rear+1)%MaxSize;
return 1;
}
//出队
int DeQueue(SqQueue *Q)
{
//判断是否为空队列
int flag= SqQueueEmpty(Q);
if(flag==1)
{
printf("空队列,出队失败!\n");
return 0;
}
int e=Q->data[Q->front];
printf("删除了%d\n",e);
Q->front=(Q->front+1)%MaxSize;
return 1;
}
//计算队列元素的个数
int Length(SqQueue *Q)
{
//公式
int len=(Q->rear+MaxSize-Q->front)%MaxSize;
return len;
}
//获取队头值
int GetHead(SqQueue *Q)
{
//判断是否为空队列
int flag= SqQueueEmpty(Q);
if(flag==1)
{
return -1;
}
int e=Q->data[Q->front];
return e;
}
//打印队列
void printSqQueue(SqQueue* Q)
{
int flag= SqQueueEmpty(Q);
if(flag==1)
{
printf("空队列!!!\n");
return;
}
int p=Q->front;
while(p!=Q->rear)
{
printf("%d\n",Q->data[p]);
p=(p+1)%MaxSize;
}
}
int main()
{
SqQueue Q;
InitSqQueue(&Q);
//入队7个数据元素
for(int i=0;i<7;i++)
{
int flag= EnQueue(&Q,i*i);
if(flag==1)
{
printf("插入成功!\n");
}
}
//打印入队后的队列
printSqQueue(&Q);
//出队4个元素
for(int i=0;i<4;i++)
{
int flag=DeQueue(&Q);
if(flag==1)
{
printf("出队成功!\n");
}
}
//打印出队后的队列
printSqQueue(&Q);
//再入队6个数据元素
for(int i=0;i<6;i++)
{
int flag= EnQueue(&Q,i*i*i);
if(flag==1)
{
printf("入队成功!\n");
}
}
//再次打印队列
printSqQueue(&Q);
//获取此时队头值
int e=GetHead(&Q);
if(e!=-1)
{
printf("队头值为%d\n",e);
}
//计算此时队列元素个数
int len= Length(&Q);
printf("元素个数为%d\n",len);
return 0;
}
2、链式队列
2.1、链式队列的基本操作
#include <stdio.h>
#include <stdlib.h>
//链式队列结点
typedef struct LinkQueueNode{
int data;
struct LinkQueueNode* next;
}LinkQueueNode;
//链式队列
typedef struct {
LinkQueueNode *front;
LinkQueueNode *rear;
}*LinkQueue;
//初始化链式队列
void InitLinkQueue(LinkQueue Q)
{
//队头指针和队尾指针同时指向头结点
Q->front=Q->rear=(LinkQueueNode*) malloc(sizeof(LinkQueueNode));
//队头指针指向NULL,表明此队列为空队列
Q->front->next=NULL;
}
//判断是否为空队列
int isEmpty(LinkQueue Q)
{
if(Q->front->next==NULL)
{
return 1;
}
else
{
return 0;
}
}
//入队
//front指针一直指向头结点,rear指针一直指向最后一个入栈的元素
int EnQueue(LinkQueue Q,int e)
{
LinkQueueNode *s=(LinkQueueNode *) malloc(sizeof(LinkQueueNode));
//如果内存申请失败则返回0并退出
if(s==NULL)
{
return 0;
}
s->data=e;
s->next=NULL;
Q->rear->next=s;
Q->rear=s;
return 1;
}
//出队
int DeQueue(LinkQueue Q)
{
int flag= isEmpty(Q);
if(flag==1)
{
return 0;
}
LinkQueueNode *p=Q->front->next;
printf("删除了%d\n",p->data);
Q->front->next=p->next;
free(p);
return 1;
}
//获取队头的元素值
int GetHead(LinkQueue Q)
{
int flag= isEmpty(Q);
if(flag==1)
{
return -1;
}
int e=Q->front->next->data;
return e;
}
//打印链式队列
void printLinkQueue(LinkQueue Q)
{
int flag= isEmpty(Q);
if(flag!=1)
{
LinkQueueNode *p=Q->front;
while (p->next!=NULL)
{
p=p->next;
printf("%d\n",p->data);
}
}
}
int main()
{
//初始化一个链式队列
LinkQueue Q;
InitLinkQueue(Q);
//入队
for(int i=0;i<8;i++)
{
int flag= EnQueue(Q,i*i);
if(flag==1)
{
printf("入队成功!\n");
}
}
//打印入队后的队列
printLinkQueue(Q);
//出队
for(int i=0;i<3;i++)
{
int flag= DeQueue(Q);
if(flag==1)
{
printf("出队成功!\n");
}
}
//打印出队后的队列
printLinkQueue(Q);
//获取队头的元素值
int e= GetHead(Q);
if(e!=-1)
{
printf("队头元素值为%d\n",e);
}
return 0;
}
3、双端队列
3.1、双端队列的基本操作
#include <stdio.h>
#include <stdlib.h>
typedef struct DeQueueNode{
int data;
struct DeQueueNode* next;
}DeQueueNode;
typedef struct {
DeQueueNode *front;
DeQueueNode *rear;
}*DeQueue;
//初始化双端队列
void InitDeQueue(DeQueue Q)
{
Q->front=Q->rear=(DeQueueNode *) malloc(sizeof(DeQueueNode));
Q->front->next=NULL;
}
//判断双端队列是否为空
int isEmpty(DeQueue Q)
{
if(Q->front->next==NULL)
{
return 1;
}
else
{
return 0;
}
}
//队头入队操作
int in_front(DeQueue Q,int e)
{
//待插入的结点s
DeQueueNode *s=(DeQueueNode *) malloc(sizeof(DeQueueNode));
//判断内存申请是否失败
if(s==NULL)
{
return 0;
}
//将数据元素的值赋给结点s
s->data=e;
//将结点插入链表中存在两种情况
int flag= isEmpty(Q);
//双端队列为空队列时
if(flag==1)
{
//s为第一个结点
Q->front->next=s;
//尾指针指向s
Q->rear=s;
}
//双端队列不为空
else
{
//将待插入结点插在头结点之后
s->next=Q->front->next;
Q->front->next=s;
}
return 1;
}
//队尾入队操作
int in_rear(DeQueue Q,int e)
{
//待插入的结点s
DeQueueNode *s=(DeQueueNode *) malloc(sizeof(DeQueueNode));
//判断内存申请是否失败
if(s==NULL)
{
return 0;
}
//将数据元素赋给结点s
s->data=e;
s->next=NULL;
//
int flag= isEmpty(Q);
//双端队列为空队列时
if(flag==1)
{
//结点s为第一个结点
Q->front->next=s;
}
//双端队列不为空时
else
{
//将待插入的结点s放在最后一个结点的后面
Q->rear->next=s;
}
//最后将尾指针指向s
Q->rear=s;
return 1;
}
//队头出队操作
int out_front(DeQueue Q)
{
//判断双端队列是否为空队列
int flag= isEmpty(Q);
if(flag==1)
{
return 0;
}
//p为待删除结点
DeQueueNode *p=Q->front->next;
int e=p->data;
printf("删除了%d\n",e);
//将p结点的下一个结点设为第一个结点
Q->front->next=p->next;
//释放p结点所占内存空间
free(p);
return 1;
}
//队尾出队操作
int out_rear(DeQueue Q)
{
//判断双端队列是否为空队列
int flag= isEmpty(Q);
if(flag==1)
{
return 0;
}
//找到最后一个结点q的前驱结点p
DeQueueNode *p=Q->front;
DeQueueNode *q=Q->rear;
int e=q->data;
printf("删除了%d\n",e);
while (p->next!=q)
{
p=p->next;
}
//将p结点的指针指向NULL
p->next=NULL;
//将尾指针指向p
Q->rear=p;
//释放q结点所占内存空间
free(q);
return 1;
}
//打印双端队列
void printDeQueue(DeQueue Q)
{
int flag= isEmpty(Q);
if(flag!=1)
{
DeQueueNode *p=Q->front;
while (p->next!=NULL)
{
p=p->next;
printf("%d ",p->data);
}
printf("\n");
}
}
int main()
{
//初始化双端队列
DeQueue Q;
InitDeQueue(Q);
int i,flag;
//队头入队
for(i=1;i<=3;i++)
{
flag= in_front(Q,i*i);
if(flag==1)
{
printf("队头入队成功!\n");
}
}
//队尾入队
for(i=1;i<=4;i++)
{
flag=in_rear(Q,i*i);
if(flag==1)
{
printf("队尾入队成功!\n");
}
}
//打印入队后的双端队列
printDeQueue(Q);
//队头出队
for(i=0;i<2;i++)
{
flag=out_front(Q);
if(flag==1)
{
printf("队头出队成功!\n");
}
}
//队尾出队
for(i=0;i<2;i++)
{
flag= out_rear(Q);
if(flag==1)
{
printf("队尾出队成功!\n");
}
}
//打印出队后的双端队列
printDeQueue(Q);
return 0;
}