队列的表示和操作

队列:队列是仅在表尾进行插入操作,在表头进行删除操作的线性表。
表尾即an端,称为队尾,表头即a1端,称为队头。
队列的存储方式:顺序队列和链式队列

队列顺序表示

#define MAXQSIZE 100   //最大队列长度	
	Typedef struct{
		QElemType *base;
		int front;  //头指针
		int rear;   //尾指针

	}SqQueue;																					

设数组大小为MAXQSIZE
则当rear = MAXQSIZE时,发生溢出,这里分为两种情况:真溢出和假溢出。
如下图所示:
队列的表示和操作_第1张图片
解决假上溢的方法——引入循环队列
实现方法:利用模(mod,取余)运算
插入元素时:Q.base[Q.rear]=x; Q.rear=(Q.rear+1)%MAXQSIZE;

删除元素时:x=Q.base[Q.front]; Q.front=(Q.front+1)%MAXQSIZE;

这里的循环队列指的是循环使用为队列分配的存储空间。

**问题:**在循环队列中,队空和队满的条件都是:front=rear
要怎么区分这两者呢?
解决方案如下:
队列的表示和操作_第2张图片

循环队列的操作——队列的初始化

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);
}

循环队列的操作——队列入队

Status EnQueue(SqQueue &Q,QElemType e){
	if((Q.rear+1)%MAXQSIZE==Q.front)  return ERROR;  //队满
	Q.base[Q.rear]=e;
	Q.rear=(Q.rear+1)%MAXQSIZE;
	return OK;
}

循环队列的操作——队列出队

Status DeQueue(SqQueue &Q,QElemType &e){
	if(Q.front==Q.rear)  return ERROR;
	e=Q.base[Q.front];   //保存队头元素
	Q.front=(Q.front+1)%MAXQSIZE;
	return OK;
}

循环队列的操作——取队头元素

SElemType GetHead(SqQueue Q){
	if(Q.front!=Q.rear)
		return Q.base[Q.front];   //返回队头指针元素的值,队头指针不变
}

队列的链式表示和实现

类型定义

# define MAXQSIZE 100
typedef struct Qnode{
	QElemType data;
	struct Qnode *next;
}Qnode,*QueuePtr;

链队列初始化

Status InitQueue(LinkQueue &Q){
	Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));  //队头,队尾指针均指向初始化结点。
	if(!Q.front)  exit(OVERFLOW);
	Q.front->next=NULL;
	return OK;
}

销毁链队列

思路:从队头结点开始,依次释放所有结点

Status DestroyQueue(LinkQueue &Q){
	while(Q.front){
		p=Q.front->next;
		free(Q.front);
		Q.front=p;
	}
	return OK;
}

插入元素e

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   //如果头结点下一结点就是尾结点,需要修改尾指针的位置。
	delete p;
	return OK;
}

获取链队列的队头元素

Status GetHead(LinkQueue Q,QElemType &e){
	if(Q.front==Q.rear)  return ERROR;
	e=Q.front->next->data;
}

你可能感兴趣的:(数据结构)