数据结构-队列


title: 数据结构-队列
date: 2022-12-30 15:31:12

队列的定义

队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性。

  • 允许删除的一端称为队头(Front)
  • 允许插入的一端称为队尾(Rear)
  • 当队列中没有元素时称为空队列
  • 队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表
  • 队列的修改是依先进先出的原则进行的。新来的成员总是加入队尾(即不允许"加塞"),每次离开的成员总是队列头上的(不允许中途离队),即当前"最老的"成员离队。

循环队列的操作

循环队列的存储结构

#define MAXSIZE 100  //队列的最大长度
typedef struct
{
	QElemType *base;	//存储空间的基地址
	int front;	//头指针
	int rear;  //尾指针
}SqQueue;

例:

typedef struct
{
	int* base;
	int front;
	int rear;
}SeQueue;

初始化

【算法步骤】

  • 为队列分配一个最大容量为MAXSIZE的数组空间,base指向指针空间的首地址。
  • 将头指针和尾指针置为0,表示队列为空。

【算法描述】

Status InitQueue(SqQueue &Q)
{//构建一个空队列
	Q.base = new QElemType(MAXSIZE); //为队列分配一个最大容量为MAXSIZE的数组空间
	if(!Q.base)
	{
		exit(OVERFLOW);	//存储空间分配失败
	}
	Q.front = Q.rear = 0; //将头指针和尾指针置为0,队列为空
	return OK;
}

例:

int InitQuene(SeQueue& q)
{
	q.base = (int*)malloc(MAXSIZE * sizeof(int)); //动态分配内存
	if (!q.base)
	{
		return false;
	}
	q.front = q.rear = 0;
	return true;
}

求队列长度

【算法描述】:

int QueueLenght(SqQueue)
{
	retturn (Q.rear - Q.front + MAXSIZE) % MAXSIZE; //对循环队列,
}

例:

//求循环队列长度
int QueueLength(SeQueue q)
{
	return (q.rear - q.front + MAXSIZE) % MAXSIZE; 
}

入队

【算法步骤】:

  • 判断队列是否满,若满则返回ERROR
  • 将新元素插入队尾
  • 队尾指针加1

【算法描述】:

//入队
Status EnQueue(SeQueue& q, QElemType e)
{ //插入元素e为Q的新队尾元素
	if ((q.rear + 1) % MAXSIZE == q.front) //若尾指针在循环意义上加1后等于头指针,表明队满
	{
		return ERROR;
	}
	q.base[q.rear] = e; //新元素插入队尾
	q.rear = (q.rear + 1) % MAXSIZE; //队尾指针加1
	return OK;
}

例:

//入队
int EnQueue(SeQueue& q, int e)
{
	if ((q.rear + 1) % MAXSIZE == q.front)
	{
		return false;
	}
	q.base[q.rear] = e;
	q.rear = (q.rear + 1) % MAXSIZE;
	return true;
}

出队

【算法步骤】:

  • 判断队列是否为空,若空则返回ERROR
  • 保存队头元素
  • 队头指针加1

【算法描述】:

//出队
Status DeQueue(SeQueue& q, QElemType& e)
{//删除q的队头元素,用e返回其值
	if (q.front == q.rear) //队空
	{
		returnERROR;
	}
	e = q.base[q.front]; //保存队头元素
	q.front = (q.front + 1) % MAXSIZE; //队头指针加1
	return OK;
}

例:

//出队
int DeQueue(SeQueue& q, int& e)
{
	if (q.front == q.rear)
	{
		return false;
	}
	e = q.base[q.front];
	q.front = (q.front + 1) % MAXSIZE;
	return e;
}

取队头元素

当队列非空时,此操作返回当前队头元素的值,队头指针保持不变

【算法描述】:

//取队头元素
QElemType GetHead(SeQueue q)
{//返回q的队头元素,不修改会头指针
	if (q.front != q.rear) //队列非空
	{
		return q.base[q.front]; //返回当前队头元素的值,队头指针保持不变
	}
}

例:

//取队头元素
int GetHead(SeQueue q)
{
	if (q.front != q.rear)
	{
		return q.base[q.front];
	}

销毁队列

【算法描述】:

Status DesQueue( SqQueue *Q )
{
    free( Q.base ) ;
    Q.base = NULL ;
    Q.front = Q.rear = 0 ;
    return OK;
}

例:

int DesQueue( SqQueue *Q )
{
    free( Q.base ) ;
    Q.base = NULL ;
    Q.front = Q.rear = 0 ;
    return ture;
}


链队列的操作

链队列的存储结构

typedef struct QNode
{
	QElemType data;
	Struct QNode *next;
}QNode, *QueuePtr;

typedef struct 
{
	QueuePtr front; //队头指针
    QueuePtr rear; //队尾指针
}LinkList;

例:

typedef struct QNode
{
	int data;
	Struct QNode *next;
}QNode, *QueuePtr;

typedef struct 
{
	QueuePtr front; //队头指针
    QueuePtr rear; //队尾指针
}LinkQueue;

初始化

【算法步骤】:

  • 生成新节点作为头节点,队头和队尾指针指向此节点
  • 头节点的指针域置空

【算法描述】:

Status InitQueue(LinkQueue &Q)
{ //构造一个空队列Q
	Q.front = Q.rear = new QNode; //生成新节点作为头节点,队头和队尾指针指向此节点
	Q.front->next = NULL; //头节点的指针域置空
    return OK;
}

例:

int InitQueue(LinkQueue &Q)
{
	Q.front = Q.rear = (QNode*)mallco(sizeof(QNode)); //生成新节点作为头节点,队头和队尾指针指向此节点
	Q.front->next = NULL; //头节点的指针域置空
    return true;
}

入队

【算法步骤】:

  • 为入队元素分配节点空间,用指针p指向。
  • 将新节点数据域置为e。
  • 将新节点插入到队尾。
  • 修改队尾指针为p。

如图:

**【算法描述】:**
Staus EnQueue (LinkQueue &Q, QElemTpye e)
{//插入元素e为Q的新队尾元素
	p = new QNode; //为入队元素分配节点空间,用指针p指向
	p->data = e;  //将新节点的数据域置为e
	p->next = NULL; //将新节点插入队尾
	Q.rear->next = p; //修改队尾指针
	Q.rear = p;
	
	return OK;
}

例:

int EnQueue (LinkQueue &Q, int e)
{//插入元素e为Q的新队尾元素
	p = (QNode *)malloc(sizeof(QNode)); //为入队元素分配节点空间,用指针p指向
	p->data = e;  //将新节点的数据域置为e
	p->next = NULL; //将新节点插入队尾
	Q.rear->next = p; //修改队尾指针
	Q.rear = p;
	
	return true;
}

出队

【算法步骤】:

  • 判断队列是否为空,若空则返回ERROR
  • 临时保存队头元素的值,以释放空间
  • 修改队头节点的指针域,指向下一个节点
  • 判断出队元素是否为最后一个元素,若是,则将队尾指针重新赋值,指向头节点

【算法描述】:

Status DeQueue(LinkQueue &Q, QElemType &e)
{//删除Q的队头元素,用e返回其值
	if(Q.front == Q.rear) //若队列为空,则返回ERROR
	{
		return ERROR;
	}
	p = Q.front->next; //p指向队头元素
	e = p->data; //e保存队头元素的值
	Q.front->next = p->next; //修改头节点的指针域
	if(Q.rear == p)  //最后一个元素被删, 队尾指针指向头节点
	{
		Q.rear = Q.front;
	}
	delete(p); //释放原队头元素的空间
	return OK;
}

例:

int DeQueue(LinkQueue &Q, int &e)
{//删除Q的队头元素,用e返回其值
	if(Q.front == Q.rear) //若队列为空,则返回ERROR
	{
		return false;
	}
	p = Q.front->next; //p指向队头元素
	e = p->data; //e保存队头元素的值
	Q.front->next = p->next; //修改头节点的指针域
	if(Q.rear == p)  //最后一个元素被删, 队尾指针指向头节点
	{
		Q.rear = Q.front;
	}
	delete(p); //释放原队头元素的空间
	return true;
}

取队头元素

【算法描述】:

QElemType GetHead(LinkQueue Q)
{//返回Q的队头元素,不修改队头指针
	if(Q.front != Q.rear) //队列非空
	{
		return Q.front->next->data; //返回队头元素的值,队头指针不变
	}
}

例:

int GetHead(LinkQueue Q)
{//返回Q的队头元素,不修改队头指针
	if(Q.front != Q.rear) //队列非空
	{
		return Q.front->next->data; //返回队头元素的值,队头指针不变
	}
}    
 

销毁链队列

【算法描述】:

Status DesQueue( SqQueue *Q )
{
    free( Q->base ) ;
    Q->base = NULL ;
    Q->front = Q->rear = 0 ;
    return OK;
}

例:

int DesQueue( SqQueue *Q )
{
    free( Q->base ) ;
    Q->base = NULL ;
    Q->front = Q->rear = 0 ;
    return ture;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值