C语言数据结构(五),队列

《C语言数据结构》严蔚敏,吴伟民版。

上章内容链接:https://blog.csdn.net/daqino1/article/details/88832307
下章内容链接:https://blog.csdn.net/daqino1/article/details/88836147

以下内容为队列

队列(queue):是一种先进先出(first in first out, 缩写FIFO)的线性表。只允许在表的一段插入,另一段进行删除。
队尾(rear):允许插入的一端。
对头(front):允许删除的一端。
双端队列(deque):可以像栈一样。也可以一端删除,另一端允许插入和删除。反之也可。

//-----------------队列的抽象化定义-------------------
ADT Queue {
	// 构造一个空队列Q
	InitQueue(&Q);
	// 队列Q被销毁,不再存在
	DestroyQueue(&Q);
	// 将Q清为空队列
	ClearQueue(&Q);
	// 若Q为空队列,则返回TRUE,否则FALSE
	QueueEmpty(Q);
	// 返回Q的元素个数,即队列的长度
	QueueLength(Q);
	// 用e返回Q的队头元素
	GetHead(Q, &e);
	// 插入元素e为Q的新的队尾元素
	EnQueue(&Q, e);
	// 删除Q的队头元素, 并用e返回其值
	DeQueue(&Q, &e);
	/* 从队头到队尾,依次对Q的每个数据元素调用函数visit()。一旦visit()失败,则操作失败。*/
	QueueTraverse(Q, visit());
}

队列也有两种存储表示:
1.链队列:用链表表示的队列。
2.循环队列:用一组地址连续的存储单元一次存放从队列头到队列尾的元素,并且附设两个指针front和rear,分别表示队列头元素和队列尾元素。

//------单链队列-------队列的链式存储结构---------------------
typedef struct QNode {
	QElemType data;
	struct QNode *next;
} QNode, *QueuePtr;

typedef struct {
	QueuePtr front;
	QueurPtr rear;
}LinkQueue;

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

//--------------------基本操作的部分算法描述-------------------
Status InitQueue(LinkQueue &Q) {
	// 构造一个空队列Q
	Q.front = Q.rear = (QueuePtr)malloc(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 0;
}

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返回其值
	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 0;
}

循环队列的模块说明如下:

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

//-------------------------------------循环队列的基本操作的算法描述----------------------------
Status InitQueue(SqQueue &Q) {
	// 构造一个空队列Q
	Q.base = (ElemType *)malloc(MAXQSIZE * sizeof(ElemType));
	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) % MAXQSIZE;
	return OK;
}

队列应用: 处理离散事件,例如:银行排队

上章内容链接:https://blog.csdn.net/daqino1/article/details/88832307
下章内容链接:https://blog.csdn.net/daqino1/article/details/88836147

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