栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言队列的基本实现

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言队列的基本实现

文章目录
    • 1.队列的简介
    • 2.队列的简单实现
    • 3.循环队列说明
    • 4.循环队列实现

1.队列的简介

队列(Queue),简称队,它也是一种运算受限的特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO)线性表。
对应我们日常生活中的情形,比如,在食堂的单窗口买饭,一个食堂阿姨每次只能给一位同学打饭,那么我们就需要排队买饭,先到的同学排在队伍的前面,后来的同学排在后面。前面的同学先买到饭然后出队离开;后面来的同学原则上只能排到队伍的后面(手动狗头)。这就是先来的先请求得到服务。再比如我们有一台网络共享打印机,网络中的任何一台机器都可以向它发出打印请求。但它每次只能服务一个,该如何处理这些请求呢?这个时候控制打印机的程序就会把请求们加入到一个队列,只要队列中有内容,打印机就会从不断地从队列头部取出请求执行打印。计算机的处理器也是一个共享的资源,很多程序或者说进程需要处理器的时间片来执行,那么这些进程也会被放入一个队列。

对于栈,插入和删除只能从一端进行;对于队列,插入和删除操作必须从不同端进行。接下来我们用两种方式来实现相关操作。

2.队列的简单实现

首先创建一个包含整型元素的数组来存储队列。下面是一种极其简单的实现方式。代码:

#include
#define MAXSIZE 10
int A[MAXSIZE];//定义一个全局整型数组存放队元素
int front = -1;
int rear = -1; //队空时将索引置为-1;
//入队操作
 void Enqueue(int x){
 	//队满则不支持入队
	 if(rear ==MAXSIZE-1){
	 	printf("Error:Queue is Full ");
	 		return ;
		 }
		 A[++rear] = x;
	 
 }
 //出队操作
 void Dequeue(){
 	if((rear ==-1)&& front ==-1){
 		printf("Error:Queue is Empty");
 		return ;
	 }
	 else if(rear == front&&(rear!=-1)){//队列只有一个元素 
	 	rear = -1;
	 	front = -1;
	 	
	 }
	 else{
	 	front  = front+1;
	 } 	 
 } 
 // 返回队尾值
 int Rear(){
 	return A[rear];
 } 
 void Print(){
 	int i;
 	printf("queue:  ");
 	for(i=front+1;i<=rear;i++){
 		printf("%d  ",A[i]);
	 }
 	printf("n");
 }
 int main(){
 	Enqueue(1);
 	Enqueue(2);
 	Enqueue(3);
 	Print();
 	Dequeue();
 	Dequeue();
 	printf("now the queue is: ");
 	Print();
 }

运行结果:

3.循环队列说明

很明显,以上的方法,我们只是利用简单的数组进行了模拟。它存在着很多的不足。比如,当我们删去队列中的元素时,我们没法使用他们留下来的空位,每一次Dequeue空下来的front位都会被闲置。这样对空间造成了很大的浪费。于是,我们设计循环数组。通过取余的操作,使front和rear指针发生改变。除此之外,我们说队列也是一种线性表,对于线性表,我们使用结构体来定义才是一种更加理想的方式。

4.循环队列实现

结构体定义:

typedef struct
{
	QElemType *base;//初始化动态分配的指定长度的空间
	int front;//头指针,若队列不空,指向队列头元素
	int rear;//尾指针,若队列不空,指向队列尾元素的下一个位置
}SqQueue;

循环队列初始化:

bool InitQueue(SqQueue *Q)
{
	Q->base=(QElemType*)malloc(maxQueueSize*sizeof(QElemType));
	if (!Q->base)
	{
		return false;
	}
	Q->front=0;
	Q->rear=0;
	return true;
}

入队函数:

bool EnQueue(SqQueue *Q,QElemType e)
{
	if ((Q->rear+1)%maxQueueSize==Q->front)//队列满
	{
		return false;
	}
	Q->base[Q->rear]=e;
	Q->rear=(Q->rear+1)%maxQueueSize;
	printf("%d successfully inn",e);
	return true;
}

出队函数:

bool DeQueue(SqQueue *Q,QElemType *e)
{
	if (Q->front==Q->rear)//队列空
	{
		return false;
	}
	*e=Q->base[Q->front];
	Q->front=(Q->front+1)%maxQueueSize;
	printf("%d successfully out!n",*e);
	return true;
}

打印函数和主函数:

void printfQueue(SqQueue Q)
{
	printf("Now the queue is:n");
	while (Q.front!=Q.rear)
	{
		if (Q.front==maxQueueSize &&(Q.rear+1)%maxQueueSize!=Q.front)
		{
			Q.front=0;
		}
		printf("%d ",Q.base[Q.front]);
		Q.front++;
	}
	printf("n");
}

int main()
{
	SqQueue *Q=(SqQueue*)malloc(sizeof(SqQueue));
	InitQueue(Q);

	EnQueue(Q,1);
	EnQueue(Q,3);
	EnQueue(Q,1);
	EnQueue(Q,4);
	printfQueue(*Q);
	QElemType *e=(QElemType*)malloc(sizeof(QElemType));
	DeQueue(Q,e);
	DeQueue(Q,e);
	EnQueue(Q,9);
	EnQueue(Q,9);
	printfQueue(*Q);

	
	return 0;
}

执行结果:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/884155.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号