数据结构与算法--队列


请结合我的另一篇文章食用 数据结构与算法–栈.

基本定义

队列是一种先进先出的线性表,只允许在一端进行插入,而在另一端进行删除。

参考完栈的实现,很容易发现,队列和栈的实现基本相同
我们这里只是简单介绍队列的基本操作和实现

基本操作

InitQueue(&Q);//队列的初始化
DestroyQueue(&Q);//队列的销毁
QueueEmpty(Q);//队列是否为空
QueueLength(Q);//队列长度
GetHead(Q,&e);//得到队首元素
EnQueue(&Q,e);//入队
DeQueue(&Q);//出队
QueueTraverse(Q,visit());//遍历

栈的表达和实现

顺序存储结构

用一组地址连续的存储单元依次存放队头到队尾的元素

类似栈实现的base和top指针,这里队列的front指针指向队列第一个元素,rear指向队列最后一个元素的下一个位置。

front = NULL 表示队列不存在;front = rear 表示空队列;rear = MAXSIZE表示队满

//简单介绍
元素入队:++rear;
元素出队:++front;

很容易看出,当出队的时候,头部存储空间无法再次使用,导致空间使用率下降,所以我们可以使用循环队列(实际只是灵活运用空间编号)

  • front指向队头,rear指向队尾下一个元素
  • front = rear表示空队列
  • 元素入队:rear = (rear+1)%MAXSIZE;
  • 元素出队:front = (front+1)%MAXSIZE;

但是通过以上定义我们可以发现一个bug:当栈为空时front = rear,但是当栈满时也是front = rear。

所以为解决以上问题,我们规定,在循环队列中,front和rear之间总是空出来一个空间.(实际上就是当rear下一个位置为front时我们就及时刹车,设置队满,不再允许元素入队)

  • front指向队首,rear指向队尾下一个位置。
  • 空队列:front = rear
  • 满队列:(rear+1)%MAXSIZE = front
  • 元素入队:rear = (rear+1)%MAXSIZE;
  • 元素出队:front = (front+1)%MAXSIZE;
  • 元素个数:cnt = (rear - front + MAXSIZE)%MAXSIZE;(C里面取模允许为负,所以我们要加上MAXSIZE)

链式存储结构

队列具有只是队头和队尾的指针(头指针尾指针

同时,队列具有头结点

头指针front指向第一个元素的前一个元素,初始化指向头结点

尾指针rear指向最后一个元素,初始化指向头结点

空队列:Q.front = Q.rear

//以下为伪代码,具体代码自行编写,可参考栈的实现
typedef struct QNode 
{
	QElemType data;
	struct QNode *next;
} QNode, *QueuePtr;

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

//元素入队(也就是队尾插入元素)
Status  EnQueue ( LinkQueue  &Q, QElemType  e )
{
    p = ( QueuePtr ) malloc ( sizeof(QNode));
    if ( !p )   
    	exit (OVERFLOW);
    p->data = e;
    p->next = NULL; //申请新结点
    Q.rear->next = p;
    Q.rear = p; //插入在队尾
    return  OK;
}

//元素入队(也就是队首删除元素)
Status  DeQueue ( LinkQueue  &Q ,QElemType  &e )
{
    if ( Q.front == Q.rear )  
    	return  ERROR;
    p = Q.front->next;
    e = p->data;     //取第一个结点
    Q.front->next = p->next;  //删除第一个结点
    if ( Q.rear == p )   //若需要删除的队头结点就是尾结点,这一步很重要
    	Q.rear = Q.front;
    free ( p );
    return  OK;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值