链队列与循环队列(伪代码和c语言实现源码)

本文详细介绍了队列的基本概念及其实现方式,包括链队列和循环队列两种主要形式,并提供了具体的C语言代码示例。

队列
队列是一种重要的线性结构,与栈相同也需要顺序表或者链表作为基础。队列是先进先出(first in first out)FIFO的线性表。

所有数据从队列的一端进入,从另一端离开。
在这里插入图片描述
队列中允许插入数据一端称队尾(rear),允许数据离开的一端称队头(front)

既可以是顺序表也可以是链表

创建一个空队列

在这里插入图片描述

入队列操作

在这里插入图片描述

出队列操作
在这里插入图片描述

实例分析
/

********************************************
 *实现一个链队列,任意输入一串字符,以@为结束标志 
 *将队列中的元素逐一取出,打印在屏幕上 
 ********************************************/ 
#include<bits/stdc++.h>
 
 
 
/********************************************* 
 *定义一个完整的队列。QNode表示队列中每个元素都是QNode 
 *链队列:包含数据域data和指针域next
 *QueuePtr为指向QNode元素的指针类型 等价于*QNode
 *再定义一个LinkQueue类型 front指向队头 rear指向队尾 
 **********************************************/ 
typedef struct QNode{
	char data;
	struct QNode *next;
}QNode , *QueuePtr;		
typedef struct{
	QueuePtr front;				//等价于QNode *front 
	QueuePtr rear;
}LinkQueue;
 
/********************************************* 
 *创建一个队列 
 *1.创建一个头结点,方便操作人为添加
 *2.队列头指针尾指针都指向这个头结点,此时队列空 
 **********************************************/ 
void initQueue(LinkQueue *q)
{
	//创建一个头结点,队头队尾指针指向该结点 
	q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));
	if(!q->front)	exit(0);	//创建头结点失败、
	q->front->next = NULL;		//头结点指针域置空 
}
 
/******************** 
 *入队列 
 *将一个QNode类型元素从队列尾部进入 
 *每当一个元素进入,队列尾指针都要修改
 *队头不变 
 *********************/
void EnQueue(LinkQueue *q, char e)
{
	QueuePtr p;
	//创建一个QNode队列元素结点 并创建QueuePtr类型变量p指向该结点 
	p = (QueuePtr)malloc(sizeof(QNode)); 
	if(!q->front)	exit(0);			 //创建头结点失败
	p->data = e;						 //数据e赋给该元素结点的数据域data 
	p->next = NULL;						 //该元素结点的指针域置空 
	q->rear ->next = p;
	q->rear = p; 
} 
 
/******************** 
 *出队列:将队列元素从头部移出 
 *队头指针:每移出数据,队头指针不改变,头结点next改变 
 *队尾指针:当队头==队尾时改变 
 *********************/
void DeQueue(LinkQueue *q, char *e)
{
	//如果队列不为空,删除q的队头元素,e返回值 
	QueuePtr p;
	if(q->front == q->rear)	return;
	p = q->front->next;						//队头元素的指针赋给p,p指向该队列第一个元素 
	*e = p->data;							//指针e将队列队头元素返回 
	q->front->next = p->next;				//将队列头元素删除 
	if(q->rear == p) q->rear = q->front;	//队头就是队尾,修改队尾指针
	free(p); 
}
/******************** 
 *测试函数 
 *********************/
int main()
{
	char e;
	LinkQueue q;
	initQueue(&q);
	printf("请向队列中输出一列字符:\n");
	scanf("%c",&e);
	while(e != '@')
	{
		EnQueue(&q , e);
		scanf("%c", &e); 
	}
	printf("结果为:\n");
	while(q.front != q.rear)
	{
		DeQueue(&q , &e);
		printf("%c",e);
	}	
	return 0;
}

一、循环队列的基础知识
1.循环队列须要几个參数来确定
循环队列须要2个參数,front和rear
2.循环队列各个參数的含义
(1)队列初始化时,front和rear值都为零;
(2)当队列不为空时,front指向队列的第一个元素,rear指向队列最后一个元素的下一个位置;
(3)当队列为空时,front与rear的值相等,但不一定为零;
3.循环队列入队的伪算法
(1)把值存在rear所在的位置;
(2)rear=(rear+1)%maxsize ,当中maxsize代表数组的长度;

程序代码:

bool Enqueue(PQUEUE Q, int val)
{
	if(FullQueue(Q))
		return false;
	else
	{
		Q->pBase[Q->rear]=val;
		Q->rear=(Q->rear+1)%Q->maxsize;
		return true;
	}
}

4.循环队列出队的伪算法

(1)先保存出队的值;

(2)front=(front+1)%maxsize ,当中maxsize代表数组的长度;

程序代码:

bool Dequeue(PQUEUE Q, int *val)
{
	if(EmptyQueue(Q))
	{
		return false;
	}
	else
	{
		*val=Q->pBase[Q->front];
		Q->front=(Q->front+1)%Q->maxsize;
		return true;
	}
}

5.怎样推断循环队列是否为空

if(front==rear)

队列空;

else

队列不空;

bool EmptyQueue(PQUEUE Q)
{
	if(Q->front==Q->rear)    //推断是否为空
		return true;
	else
		return false;
}

6.怎样推断循环队列是否为满

这个问题比較复杂,如果数组的存数空间为7,此时已经存放1,a,5,7,22,90六个元素了,如果在往数组中加入一个元素,则rear=front;此时,队列满与队列空的推断条件front=rear同样,这种话我们就不能推断队列究竟是空还是满了;

解决问题有两个办法:一是添加一个參数,用来记录数组中当前元素的个数;第二个办法是,少用一个存储空间,也就是数组的最后一个存数空间不用,当(rear+1)%maxsiz=front时,队列满;

bool FullQueue(PQUEUE Q)
{
	if(Q->front==(Q->rear+1)%Q->maxsize)    //推断循环链表是否满,留一个预留空间不用
		return true;
	else
		return false;
}

附录:
queue.h文件代码:

#ifndef __QUEUE_H_
#define __QUEUE_H_
typedef struct queue 
{
	int *pBase;
	int front;    //指向队列第一个元素
	int rear;    //指向队列最后一个元素的下一个元素
	int maxsize; //循环队列的最大存储空间
}QUEUE,*PQUEUE;

void CreateQueue(PQUEUE Q,int maxsize);
void TraverseQueue(PQUEUE Q);
bool FullQueue(PQUEUE Q);
bool EmptyQueue(PQUEUE Q);
bool Enqueue(PQUEUE Q, int val);
bool Dequeue(PQUEUE Q, int *val);
#endif


queue.c文件代码:



#include<stdio.h>
#include<stdlib.h>
#include"malloc.h"
#include"queue.h"
/***********************************************
Function: Create a empty stack;
************************************************/
void CreateQueue(PQUEUE Q,int maxsize)
{
	Q->pBase=(int *)malloc(sizeof(int)*maxsize);
	if(NULL==Q->pBase)
	{
		printf("Memory allocation failure");
		exit(-1);        //退出程序
	}
	Q->front=0;         //初始化參数
	Q->rear=0;
	Q->maxsize=maxsize;
}
/***********************************************
Function: Print the stack element;
************************************************/
void TraverseQueue(PQUEUE Q)
{
	int i=Q->front;
	printf("队中的元素是:\n");
	while(i%Q->maxsize!=Q->rear)
	{
		printf("%d ",Q->pBase[i]);
		i++;
	}
	printf("\n");
}
bool FullQueue(PQUEUE Q)
{
	if(Q->front==(Q->rear+1)%Q->maxsize)    //推断循环链表是否满,留一个预留空间不用
		return true;
	else
		return false;
}
bool EmptyQueue(PQUEUE Q)
{
	if(Q->front==Q->rear)    //推断是否为空
		return true;
	else
		return false;
}
bool Enqueue(PQUEUE Q, int val)
{
	if(FullQueue(Q))
		return false;
	else
	{
		Q->pBase[Q->rear]=val;
		Q->rear=(Q->rear+1)%Q->maxsize;
		return true;
	}
}

bool Dequeue(PQUEUE Q, int *val)
{
	if(EmptyQueue(Q))
	{
		return false;
	}
	else
	{
		*val=Q->pBase[Q->front];
		Q->front=(Q->front+1)%Q->maxsize;
		return true;
	}
}

转载自:https://blog.youkuaiyun.com/qq_38663663/article/details/80810441
https://www.cnblogs.com/mfrbuaa/p/4050998.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值