顺序队列
Posted 四季帆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了顺序队列相关的知识,希望对你有一定的参考价值。
1. 队列的概念
在单链表中,我们只能对他的链表表尾进行插入,对链表的表头进行结点的删除,这样强限制性的链表,就是我们所说的队列。
通常,称进数据的一端为 队尾,出数据的一端为 队头,数据元素进队列的过程称为 入队,出队列的过程称为出队。
2. 数组实现
#include<stdio.h>
#include<stdlib.h>
typedef struct Qnode
{
int *Data;
int Front,Rear; //Front表示队头,Rear表示队尾
int Max;
} *Queue;
//创建一个空队列
Queue CreateQueue(int max)
{
Queue q = (Queue)malloc(sizeof(struct Qnode));
q->Data = (int *)malloc(sizeof(int) * max);
q->Front = q->Rear=0;
q->Max = max;
return q;
}
//入队
void AddQueue(Queue q, int data)
{
if(q->Rear == q->Max)
{
printf("Queue is full!\\n");
}
else
{
q->Data[q->Rear] = data;
q->Rear = q->Rear+1;
}
}
//出队
void OutQueue(Queue q, int *data)
{
if(q->Front == q->Rear)
{
printf("Queue is empty\\n");
}
else
{
*data = q->Data[q->Front];
q->Front = q->Front+1;
}
}
int main()
{
int i, temp;
Queue q;
q=CreateQueue(10); //创建一个队长为10的空队列
for(i=0;i<10;i++) //入队10个数字
AddQueue(q,i);
for(i=0;i<5;i++) //出队5个数字并打印
{
OutQueue(q, &temp);
printf("%d\\n", temp);
}
return 0;
}
通过数组实现的顺序链表有一个问题,那就是队列满了以后无法再进行入队操作,即使是通过出队操作清空了的存储空间,也没办法再次被入队操作使用,这种情况称之为“假溢出”,所以用数组实现的顺序队列基本上可以认为是毫无用处!!!
3. 链表实现
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *next;
}QueueNode;
typedef struct{
QueueNode *front; /*头指针*/
QueueNode *rear;
}LinkQueue;
/*初始化队列,将顺序队列置空*/
LinkQueue *CreateQueue()
{
LinkQueue *Q = malloc(sizeof(LinkQueue));
Q->front = NULL;
Q->rear = NULL;
return Q;
}
/* 进入队列,添加尾结点 */
void AddQueue(LinkQueue *Q, int data)
{
/*将元素x插入链队列尾部*/
QueueNode *p = (QueueNode *)malloc(sizeof(QueueNode));/*申请新结点*/
if (!p) //申请内存失败
{
printf("malloc fail\\n");
}
p->data = data;
p->next = NULL;
if (Q->rear == NULL) /* 队列为空 */
{
Q->rear = p;
Q->front = Q->rear;
}
else /* 队列非空 */
{
Q->rear->next = p; /*链表的原尾节点Q->rear*/
Q->rear = p; /*尾节点指针指向新的尾节点*/
}
}
/* 出队,删除头节点 */
void OutQueue(LinkQueue *Q, int *data)
{
QueueNode *p;
if (Q->front == NULL) /* 队列为空 */
{
printf("Queue is empty\\n");
return;
}
p = Q->front; /*指向头结点*/
*data = p->data; /*保存头结点的数据*/
if(Q->front == Q->rear) /*只有一个节点时(即只剩下头节点时),针对只入队了一个节点和出队到只剩下一个节点两种情况*/
Q->front = NULL;
else
Q->front = p->next; /*将头结点从链上摘下, 原第二节点变为头节点*/
free(p); /*释放原头结点*/
}
void main()
{
LinkQueue *s;
int select, res;
int value, i;
s = CreateQueue();/*初始化队列,将顺序队列置空*/
for(i=0;i<10;i++) /*入队10个数字*/
{
AddQueue(s,i);
}
for(i=0;i<11;i++) /*出队11个数字*/
{
OutQueue(s,&value);
printf("%d\\n", value);
}
}
通过链表实现的顺序队列避免了数组实现的问题,因为链表实现的队列的存储空间是动态申请和释放的,出队操作释放掉的存储空间是可以再次被入队操作申请的,不会出现“假溢出”的情况。
以上是关于顺序队列的主要内容,如果未能解决你的问题,请参考以下文章