数据结构-----队列

队列 是一种 先进先出 的线性表。它只允许在表的一端进行插入,而在另一端删除元素。在队列中,允许插入的一端叫做 队尾,允许删除的一端称为 队头

用链表表示的队列简称为 链队列,一个链队列显然需要两个分别指示队头和队尾的指针(分别称为头指针和尾指针)才能唯一确定。空的链队列的判决条件为头指针和尾指针均指向头结点。

链队列的模块说明:

// ===== ADT Queue 的表示与实现=====

// ----- 单链队列——队列的链式存储结构 -----
typedef struct QNode {
	QElemType			data;
	struct QNode		* next;
} QNode, * QueuePtr;
typedef struct {
	QueuePtr		front;	// 	队头指针
	QueuePtr		rear;	// 	队尾指针
} LinkQueue;

// ----- 基本操作的函数原型说明 -----
Status InitQueue (LinkQueue &Q)
	// 构造一个空队列Q
Status DestroyQueue (LinkQueue &Q)
	// 销毁队列Q,Q不在存在
Status ClearQueue (LinkQueue &Q)
	// 将Q清为空队列
Status QueueEmpty (LinkQueue &Q)
 	// 若队列为空队列,则返回TRUE,否则返回FALSE
 Status QueueLength (LinkQueue &Q)
 	// 返回Q的元素个数,即为队列的长度
 Status GetHead (LinkQueue Q, QElemType &e)
 	// 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
 Status EnQueue (LinkQueue &Q, QElemType e)
 	// 插入元素e为Q的新的队尾元素
 Status DeQueue (LinkQueue &Q, QElemType &e)
 	// 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
 Status QueueTraverse (LinkQueue Q, visit())
 	// 从队头到队尾依次对队列Q中每个元素调用函数visit()。一旦visit失败,则操作失败。

// ----- 基本操作的算法描述(部分) -----
Status InitQueue (LinkQueue &Q) {
	// 构造一个空队列Q
	Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
	if ( !Q.front ) exit (OVERFLOW);		// 存储分配失败
	Q.front->next=NULL;
	return OK;
}

Status DestroyQueue(LinkQueue &Q) {
	// 销毁队列Q
	while (Q.front) {
		Q.rear = Q.front->next;
		free(Q.front);
		Q.front = Q.rear;
	}
	return OK;
}

Status EnQueue (LinkQueue &Q, QElemType e) {
	// 插入元素e为Q的新的队尾元素
	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) {
	// 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
	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;
}

一般情况下,删除队列元素时仅需修改头结点中的指针,但当队列中最后一个元素被删后,队列尾指针也丢失了,因此需对队尾指针重新赋值(指向头结点)。

循环队列类型的模块说明:

// ----- 循环队列——队列的顺序存储结构 -----
# define MAXQSIZE	100		// 最大队列长度
typedef struct {
	QElemType *base;		// 初始化的动态分配存储空间
	int front;				// 头指针,若队列不空,指向队列头元素
	int rear;				// 尾指针,若队列不空,指向队列尾元素的下一个位置
} SqQueue;

// ----- 循环队列的基本操作的算法描述 -----
Status IniQueue (SqQueue &Q) {
	// 构造一个空队列Q
	Q.base = (QElemType *) malloc (MAXQSIZE * sizeof (QElemType));
	if (!Q.base) exit(OVERFLOW);		// 存储分配失败
	Q.front = Q.rear = 0;
	return OK;
}

int QueueLength (SqQueue Q) {
	// 返回Q的元素个数,即队列的长度
	return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}

Status EnQueue (SqQueue &Q, QElemType e) {
	// 插入元素e为Q的新的队尾元素
	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) {
	// 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
	if (Q.front == Q.rear) return ERROR;
	e = Q.base[Q.front];
	Q.front = (Q.front+1) % MAXSIZE;
	return OK;
}

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