数据结构之队列(顺序队和链队)(C语言附完整代码)


一、定义

队列简称队,它是一种操作受限的线性表,其限制为仅允许在表的一端进行插入操作,而在表的另一端进行删除操作。把进行插入的一端称为队尾,把进行删除的一端称为队头或队首。向队列中插入新元素称为进队或入队,从队列中删除元素称为出队或离队。由于队列的插入和删除操作分别是在各自的一端进行的,每个元素必然按照进入的次序出队,所以又把队列称为先进先出表

在这里插入图片描述

采用顺序存储结构的队列称为顺序队

声明顺序队

typedef struct 
{	
	ElemType data[MaxSize];  //存放队中元素
	int front,rear;		//队首和队尾指针
} SqQueue;

采用链式存储结构的队列称为链队

声明链队

typedef struct DataNode
{	
	ElemType data;
	struct DataNode *next;
} DataNode;				//链队数据结点类型
typedef struct
{	
	DataNode *front;
	DataNode *rear;
} LinkQuNode;			//链队类型

二、基本运算

顺序队

设计顺序队基本运算算法四要素
1.队空的条件:q->front ==q->rear;
2.队满的条件:q->rear ==MaxSize-1(data数组的最大下标);
3.元素e进队操作:先将rear加1,然后将元素e放在data数组的rear位置;
4元素出队操作:先将front加1,然后取出data数组front位置的元素。

初始化队列

void InitQueue(SqQueue *&q)
{
	q=(SqQueue *)malloc (sizeof(SqQueue));
	q->front=q->rear=-1; 
}

构造一个空队列q,将front和rear指针均设置为初始值-1。
本算法的时间复杂度为O(1)

销毁队列

void DestroyQueue(SqQueue *&q)			
{
	free(q);//销毁队列
}

释放队列q占用的空间
本算法的时间复杂度为O(1)

判断队列是否为空

bool QueueEmpty(SqQueue *q)				//判断队列是否为空
{
	return(q->front==q->rear);
}

队列为空返回true,否则返回false。
本算法的时间复杂度为O(1)

进队列

bool enQueue(SqQueue *&q,ElemType e)	//进队
{
	if (q->rear==MaxSize-1)				//队满上溢出
		return false;					//返回假
	q->rear++;							//队尾增1
	q->data[q->rear]=e;					//rear位置插入元素e
	return true;						//返回真
}

先判断队列是否为满,如果为满则返回false,否则先将rear加1,然后将元素e放到该位置,最后返回true。
本算法的时间复杂度为O(1)

出队列

bool deQueue(SqQueue *&q,ElemType &e)	//出队
{
	if (q->front==q->rear)				//队空下溢出
		return false;
	q->front++;
	e=q->data[q->front];
	return true;
}

先判断队列是否为空,如果为空则返回false,否则先将队头指针加1,然后将该位置元素的值赋给e,最后返回true。
本算法的时间复杂度为O(1)

链队

设计链队基本运算算法四要素
1.队空的条件:q->front ==NULL(或q->rear ==NULL);
2.队满的条件:不存在;
3.元素e进队操作:新建一个结点存放元素e(由p指向它),将结点p插入作为尾结点;
4元素出队操作:取出队首结点的data值并将其删除。

初始化队列

void InitQueue(LinkQuNode *&q)
{	
	q=(LinkQuNode *)malloc(sizeof(LinkQuNode));
	q->front=q->rear=NULL;  //将front和rear置为NULL
}

构造一个空队列(即创建一个链队结点),将front和rear置为NULL。
本算法的时间复杂度为O(1)

销毁队列

void DestroyQueue(LinkQuNode *&q)
{
	DataNode *p=q->front,*r;//p指向队头数据结点
	if (p!=NULL)			//释放数据结点占用空间
	{
		r=p->next;
		while (r!=NULL)
		{
			free(p);
			p=r;r=p->next;
		}
	}
	free(p);
	free(q);				//释放链队结点占用空间
}

从q->front结点开始,依次释放各结点内存。

本算法的时间复杂度为O(n)

判断队列是否为空

bool QueueEmpty(LinkQuNode *q)
{
	return(q->rear==NULL);
}

q->rear=0时,队列为空,判断q->rear是否为0即可。
本算法的时间复杂度为O(1)

进队列

void enQueue(LinkQuNode *&q,ElemType e)
{
	DataNode *p;
	p=(DataNode *)malloc(sizeof(DataNode));
	p->data=e;
	p->next=NULL;
	if (q->rear==NULL)		//若链队为空,则新结点是队首结点又是队尾结点
		q->front=q->rear=p;
	else
	{	
	    q->rear->next=p;	//将p结点链到队尾,并将rear指向它
		q->rear=p;
	}
}

创建一个新结点(由p指向它)存放元素e的值。如果队列为空,则将链队front和rear指针均指向p结点,否则将p插入到单链表的末尾,并让rear指针指向它。
本算法的时间复杂度为O(1)

出队列

bool deQueue(LinkQuNode *&q,ElemType &e)
{
	DataNode *t;
	if (q->rear==NULL)		//队列为空
		return false;
	t=q->front;				//t指向第一个数据结点
	if (q->front==q->rear)  //队列中只有一个结点时
		q->front=q->rear=NULL;
	else					//队列中有多个结点时
		q->front=q->front->next;
	e=t->data;
	free(t);
	return true;
}

先判断队列是否为空,如果为空则返回false,否则将首结点的值赋给e,并将其删除,如果队列中只有一个元素,则需将链队的front和rear均置为NULL,表示链队为空,最后返回true。
本算法的时间复杂度为O(1)

三、完整代码

顺序队

#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
typedef char ElemType;
typedef struct 
{	
	ElemType data[MaxSize];
	int front,rear;						//队头和队尾指针
} SqQueue;
void InitQueue(SqQueue *&q)
{	q=(SqQueue *)malloc (sizeof(SqQueue));
	q->front=q->rear=-1;
}
void DestroyQueue(SqQueue *&q)			//销毁队列
{
	free(q);
}
bool QueueEmpty(SqQueue *q)				//判断队列是否为空
{
	return(q->front==q->rear);
}
bool enQueue(SqQueue *&q,ElemType e)	//进队
{	if (q->rear==MaxSize-1)				//队满上溢出
		return false;					//返回假
	q->rear++;							//队尾增1
	q->data[q->rear]=e;					//rear位置插入元素e
	return true;						//返回真
}
bool deQueue(SqQueue *&q,ElemType &e)	//出队
{	if (q->front==q->rear)				//队空下溢出
		return false;
	q->front++;
	e=q->data[q->front];
	return true;
}
int main()
{
	SqQueue *q;     //创建队列q  
	ElemType e;
	InitQueue(q);   //初始化队
	enQueue(q,'a');
	enQueue(q,'b');
	enQueue(q,'c'); //依次进队a,b,c
	deQueue(q,e);
	printf("%c\n",e);   //出队元素a 
	deQueue(q,e);
	printf("%c\n",e);  //出队元素b 
	deQueue(q,e);
	printf("%c\n",e);  //出队元素c
	DestroyQueue(q);  //销毁队 
	return 0; 
}

链队

#include <stdio.h>
#include <malloc.h>
typedef char ElemType;
typedef struct DataNode
{	
	ElemType data;
	struct DataNode *next;
} DataNode;				//链队数据结点类型
typedef struct
{	
	DataNode *front;
	DataNode *rear;
} LinkQuNode;			//链队类型
void InitQueue(LinkQuNode *&q)
{	
	q=(LinkQuNode *)malloc(sizeof(LinkQuNode));
	q->front=q->rear=NULL;
}
void DestroyQueue(LinkQuNode *&q)
{
	DataNode *p=q->front,*r;//p指向队头数据结点
	if (p!=NULL)			//释放数据结点占用空间
	{	r=p->next;
		while (r!=NULL)
		{	free(p);
			p=r;r=p->next;
		}
	}
	free(p);
	free(q);				//释放链队结点占用空间
}
bool QueueEmpty(LinkQuNode *q)
{
	return(q->rear==NULL);
}
void enQueue(LinkQuNode *&q,ElemType e)
{	DataNode *p;
	p=(DataNode *)malloc(sizeof(DataNode));
	p->data=e;
	p->next=NULL;
	if (q->rear==NULL)		//若链队为空,则新结点是队首结点又是队尾结点
		q->front=q->rear=p;
	else
	{	q->rear->next=p;	//将p结点链到队尾,并将rear指向它
		q->rear=p;
	}
}
bool deQueue(LinkQuNode *&q,ElemType &e)
{	DataNode *t;
	if (q->rear==NULL)		//队列为空
		return false;
	t=q->front;				//t指向第一个数据结点
	if (q->front==q->rear)  //队列中只有一个结点时
		q->front=q->rear=NULL;
	else					//队列中有多个结点时
		q->front=q->front->next;
	e=t->data;
	free(t);
	return true;
}
int main()
{
	LinkQuNode *q;     //创建队列q  
	ElemType e;
	InitQueue(q);   //初始化队
	enQueue(q,'a');
	enQueue(q,'b');
	enQueue(q,'c'); //依次进队a,b,c
	deQueue(q,e);
	printf("%c\n",e);   //出队元素a 
	deQueue(q,e);
	printf("%c\n",e);  //出队元素b 
	deQueue(q,e);
	printf("%c\n",e);  //出队元素c
	DestroyQueue(q);  //销毁队 
	return 0; 
} 

参考资料:
李春葆《数据结构教程》(第五版)

  • 9
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
顺序队列的实现: ``` #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct{ int data[MAXSIZE]; int front,rear; // front,rear分别指向头和尾位置 }SqQueue; // 初始化队列 void InitQueue(SqQueue *q){ q->front = q->rear = 0; } // 判断队列是否为空 int IsEmpty(SqQueue q){ if(q.front == q.rear) // 队列为空的条件 return 1; else return 0; } // 入队操作 int EnQueue(SqQueue *q, int x){ if((q->rear+1) % MAXSIZE == q->front) // 队列满的条件 return 0; q->data[q->rear] = x; q->rear = (q->rear + 1) % MAXSIZE; return 1; } // 出操作 int DeQueue(SqQueue *q, int *x){ if(q->front == q->rear) // 队列为空的条件 return 0; *x = q->data[q->front]; q->front = (q->front + 1) % MAXSIZE; return 1; } int main(){ SqQueue q; int i,x; InitQueue(&q); for(i=0; i<5; i++){ scanf("%d",&x); EnQueue(&q,x); } while(!IsEmpty(q)){ DeQueue(&q,&x); printf("%d ",x); } return 0; } ``` 链队列的实现: ``` #include <stdio.h> #include <stdlib.h> typedef struct QNode{ int data; struct QNode *next; }QNode,*QueuePtr; typedef struct{ QueuePtr front,rear; // front指向头,rear指向尾 }LinkQueue; // 初始化队列 void InitQueue(LinkQueue *q){ q->front = q->rear = (QueuePtr)malloc(sizeof(QNode)); if(!q->front) exit(1); // 分配空间失败,直接退出 q->front->next = NULL; } // 判断队列是否为空 int IsEmpty(LinkQueue q){ if(q.front == q.rear) // 队列为空的条件 return 1; else return 0; } // 入队操作 int EnQueue(LinkQueue *q, int x){ QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); if(!p) return 0; // 分配空间失败,返回0 p->data = x; p->next = NULL; q->rear->next = p; q->rear = p; return 1; } // 出操作 int DeQueue(LinkQueue *q, int *x){ if(q->front == q->rear) // 队列为空的条件 return 0; QueuePtr p = q->front->next; *x = p->data; q->front->next = p->next; if(q->rear == p) // 若队列中只有一个元素,那么p出后,rear也需要改变 q->rear = q->front; free(p); return 1; } int main(){ LinkQueue q; int i,x; InitQueue(&q); for(i=0; i<5; i++){ scanf("%d",&x); EnQueue(&q,x); } while(!IsEmpty(q)){ DeQueue(&q,&x); printf("%d ",x); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hello_world&&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值