顺序队列

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);
	}
}

通过链表实现的顺序队列避免了数组实现的问题,因为链表实现的队列的存储空间是动态申请和释放的,出队操作释放掉的存储空间是可以再次被入队操作申请的,不会出现“假溢出”的情况。

 

 

以上是关于顺序队列的主要内容,如果未能解决你的问题,请参考以下文章

# Java 常用代码片段

scrapy按顺序启动多个爬虫代码片段(python3)

html 将以编程方式附加外部脚本文件的javascript代码片段,并按顺序排列。用于响应式网站,其中ma

C++数据结构——顺序队列(基本代码实现与案例)

如何只用队头指针实现顺序循环队列?

顺序队列代码