线性结构 队列


一、队列的定义

队列(Queue) 是具有一定操作约束的线性表,插入和删除操作有一定要求:只能在一端插入,而在另一端删除。
遵循规则:先进先出FIFO(Fist In First Out) 。

二、抽象数据类型

ADT Queue{
数据对象:D={ ai |ai∈ ElemSet, i=1,2,…,n, n >=0 }
数据关系:R={ < a(i-1), ai > | a(i-1),ai 属于 D , i=1,2,…,n }//a1端为队头
基本操作:InitQueue (&Q) //构造空队列
DestroyQueue (&Q) //销毁队列
ClearQueue (&Q) //清空队列
QueueEmpty(Q) //判空. 空–TRUE,
QueueLength(Q) //取队列长度
GetHead (Q,&e) //取队头元素,
EnQueue (&Q,e) //入队列
DeQueue (&Q,&e) //出队列
QueueTraverse(Q) //遍历
} ADT Queue

三、顺序存储——循环队列

基本思路:

利用一组地址连续的存储单元依次存放自对头到队尾的元素,同时设立front和rear两个指示器(int变量),分别指向队头元素的前一个位置和队尾元素的位置(数组下标)。
此时: 初始化时: front=rear=0; 空队列: front==rear; 入队: base[++rear]=x;出队: x=base[++front];
出现问题:真假溢出
(数组大小M=5)
溢出

解决途径——循环队列:

思路:base[0]接在base[M-1]之后,若rear+1==M,则令rear=0;
实现:利用“模”运算
入队:rear=(rear+1)%M;base[rear]=x;
出队:front=(front+1)%M;x=base[front];
为了区分队满和队空,需令设一个标志(少用一个空间):
队满表示:(rear+1)%M == front (rear指示空间不能用)
队空表示:rear == front

存储结构

#define MAXQSIZE 100 
typedef struct{
	QElemType *base;/*初始化的动态分配存储空间*/
	int front;		/*头指示器*/
	int rear;		/*尾指示器*/
}SqQueue;
 

部分操作

  • 初始化
Status InitQueue (SqQueue &Q){
	Q.base = new QElemType[MAXQSIZE];
	if(!Q.base) exit(OVERFLOW);
	Q.front=Q.rear=0;
	return OK;
}

初始化

  • 求队列长度
int QueueLength(SqQueue Q){
	return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}

Ex
在这里插入图片描述

  • 元素入队
Status EnQueue(SqQueue &Q,QElemType e){
	if((Q.rear+1)%MAXQSIZE==Q.front)
		return ERROR;
	Q.rear = (Q.rear+1)%MAXQSIZE;/*修改队尾指针*/
	Q.base[Q.rear] = e;			/*新元素插入队尾*/
	return OK;
}
  • 元素出队
Status DeQueue(SqQueue &Q,QElemType &e){
	if(Q.front == Q.rear) return ERROR;
	Q.front = (Q.front+1)%MAXQSIZE;/*修改队尾指针*/
	e = Q.base[Q.front];		   /*取出队首元素*/
	return OK;
}
  • 取队头元素(不出队)
Status GetHead(SqQueue &Q,QElemType &e){
	if(Q.front == Q.rear) return ERROR;
	Q.front = (Q.front+1)%MAXQSIZE;/*修改队尾指针*/
	return OK;

四、链式存储——链式队列

存储结构

typedef struct Node{
ElementType  Data;
struct Node  *Next;
}QNode; 
typedef struct {        /* 链队列结构*/
QNode  *rear;      /* 指向队尾结点*/
QNode  *front;     /* 指向队头结点*/
} LinkQueue;LinkQueue  *PtrQ ;

图示
不带头结点的链式队列出队操作的一个示例:

ElementType DeleteQ ( LinkQueue  *PtrQ ){    
	Qnode  *FrontCell; 
	ElementType FrontElem;
	if  ( PtrQ->front == NULL) {
		printf(“队列空”);     
		return ERROR;
	} 
	FrontCell = PtrQ->front;
	if ( PtrQ->front == PtrQ->rear)     /* 若队列只有一个元素*/
		PtrQ->front = PtrQ->rear = NULL;/* 删除后队列置为空*/
	else 
        PtrQ->front = PtrQ->front->Next;
    FrontElem = FrontCell->Data;
    free( FrontCell );                   /* 释放被删除结点空间*/
    return  FrontElem;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值