栈和队列(2)——队列的相关操作

1.队列的结构

1.队列的概念

队列是只允许在一端进行插入删除的操作,在另一端进行删除的线性表,队列中的元素遵循先进先出即FIFO的特性。

元素入队:从队尾一端进行插入。

元素出队:从队头一端进行删除。

队列的操作即如上图所示,由FIFO的特性可以知道,元素进队顺序一旦固定,出队顺序唯一。

2.队列数据结构

那么,根据这种数据结构,我们使用顺序表形式对其进行定义。

首先,定义如下图所示的结点结构,由于要对两侧进行操作,队列里需要两个方向,即两种运作方式的结点,接着定义队列结构如下图所示。

typedef int QDataType;
 
typedef struct QNode{
    struct QueueNode* next;
	QDataType val;
}QNode;

typedef struct Queue{
    QNode* phead;
    QNode* ptail;
    int size;
}

这种结构即可双向操作完成FIFO的功能。

3.队列的初始化

下面完成对队列的初始化部分。

void QueueInit(Queue* pq) {
	assert(pq);
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

4.队列的销毁

队列的销毁与栈的结构略有不同,队列可以进行顺序遍历,使用cur指针一个节点一个节点地进行释放。其余重点跟栈的要求一致。

void QueueDestroy(Queue* pq) {
	assert(pq);
	Qnode* cur = pq->phead;
	while (cur) {
		Qnode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

2.队列的插入和删除

1.插入

队列的插入操作同顺序表,大体思路是需要生成节点然后进行尾插。首先的操作还是判满然后对队列进行扩容,其次把需要进行操作的元素值赋给新节点,此时检测ptail是否为空,若为空直接把新节点复制进去即可,少了这一步的话next为空将会触发断言。接着就是经典的尾插语句把新节点尾插进去,接着size++,让出下一次插入的空间。

void QueuePush(Queue* pq, QDataType x) {
	assert(pq);
	Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));
	if (newnode == NULL) {
		perror("malloc fail!");
		return;
	}
	newnode->val = x;
	newnode->next = NULL;
	if (pq->ptail == NULL) {
		pq->phead = pq->ptail = newnode;
	}
	else {
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}

2.删除

对于队列进行元素删除,还是要判空,再进行操作,以及要加上头结点不能空。删除就是简单的一个头删操作,如果头被删了,把尾也置空,防止对空队列进行后续操作,然后把size--即可。

void QueuePop(Queue* pq) {
	assert(pq);
	assert(pq->phead);
	assert(pq->size > 0);
	Qnode* prev = pq->phead;
	pq->phead = pq->phead->next;
	free(prev);
	prev = NULL;

	if (pq->phead == NULL) {
		pq->ptail = NULL;
	}
		
	pq->size--;
}

3.队列的其余操作

其余操作并非不重要,反而这才是队列的精华。

比如说如何实现FIFO?

这时,我们选择的头结点和尾结点就能体现出他们的作用。

1.取队头元素

QDataType QueueFront(Queue* pq) {
    assert(pq);
    assert(pq->phead);

    return pq->phead->val;
}

2.取队尾元素

QDataType QueueBack(Queue* pq) {
	assert(pq);
	assert(pq->ptail);

	return pq->ptail->val;
}

上面两个代码虽然简单,对于完成FIFO功能,只需取队头元素即可。

3.队列判空以及计算大小

bool QueueEmpty(Queue* pq) {
	assert(pq);

	return pq->phead == NULL;
}
int QueueSize(Queue* pq) {
	assert(pq);

	return pq->size;
}

这两份代码与栈类似,不多赘述。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值