链式队列的基本操作

什么是队列

1、先进先出的线性表
2、只在队头删除
3、在队尾插入

什么是链式队列

1、用链表表示的队列叫做链式队列
2、两个分别指向队头和队尾的指针
3、空的链队列的判断条件是队头和队尾指针同时指向头结点

链式队列的存储结构
typedef struct QNode {
	QElemType data;  //队列元素
	struct QNode *next; //指向下一个元素节点
}QNode, *QueuePtr;
typedef struct {
	QueuePtr front;  //队头指针
	QueuePtr rear; //队尾指针
}LinkQueue;
初始化
void InitQueue(LinkQueue &Q) {
	QNode *QHead = (QNode*)malloc(sizeof(QNode));//构建头结点
	Q.rear = Q.front = QHead; //初始化队头和队尾指针,指向头结点
	Q.front->next = Q.rear->next = NULL;//在使用前把指针域设置为NULL
}
清空队列

只是清空队列
让队列重置成刚初始化的样子

void ClearQueue(LinkQueue &Q){
	Q.rear = Q.front; //初始化为头尾都指向同一处
	QueuePtr p,q;//设置变量来进行指针的移动
	p = Q.front->next;//之后清空头结点后面节点的数据和指针域
	Q.front->next = NULL;
	while(p) {
		q = p;
		free(q);
		p = p->next;//p指针进行更替滑动
	}
}
销毁队列

使得队列不再存在
所以是需要free头结点的

void DestroyQueue(LinkQueue &Q) {
	while (Q.front) {
		Q.rear = Q.front->next; //让尾节点作为滑动的指针,从front开始往后清空
		free(Q.front);
		Q.front = Q.rear;
	}
}
求队列长度

设置计时器
从头结点开始累加
头结点是没有存储数据的
所以计数器从1开始
如果计数器从0开始
p=Q.front;

int QueueLength(LinkQueue Q) {
	QueuePtr p;
	int i = 1;
	p = Q.front->next;//从front开始
	while (p != Q.rear) {
		printf("data:%d\n", p->data);
		i++;
		p = p->next;
		printf("i:%d\n", i);
	}
	return i;
}

在求队列长度时候,起初我的做法为下。其实是大错特错的
因为这里是链式存储的,不可以直接通过尾指针-头指针返回的是之间的地址差。

而为什么在栈中可以S.base-S.top,因为栈是顺序存储的。top和base相当于栈的下标,地址是连续一片的。所以可以。

return Q.rear-Q.front
添加队列元素
void EnQueue(LinkQueue &Q,QElemType data) {
	QueuePtr L = (QNode*)malloc(sizeof(QNode));//创建新节点
	L->data = data;//把要插入的数据放进节点中
	L->next = NULL;//因为在队尾插入,所以始终队尾的next为NULL
	Q.rear->next = L;//把新节点放在当前队尾的后面
	Q.rear = L;//然后更新队尾指针,指向新节点
	//
}
空队列

队列为空的条件为头指针和尾指针都指向头结点

bool QueueEmpty(LinkQueue Q) {
	if (Q.rear == Q.front)
		return true;
	return false;
}
获取队头元素
Status GetHead(LinkQueue Q,QElemType &elem){
	elem = Q.front->next->data;
	return elem;
}
删除队列元素
Status DeQueue(LinkQueue &Q) { //删除队头元素
	if (Q.rear == Q.front)//如果队列为空
		return -1;//结束
	QueuePtr p;
	//通过移动Q.front指针删除
	//其实还存在
	//只是不能再访问了
	QElemType e;
	p = Q.front->next;//使用p记录要被删除的节点
	e = p->data;//把删除的节点的数据给e
	Q.front->next = p->next;//把p后面的节点给头结点的后面
	//如果队列的最后一个元素被删除了,要让尾指针重新指向头结点
	if (Q.rear == p) {
	//就要让尾指针重新等于头指针
		Q.rear = Q.front;//如果只有一个元素,然后被删除了
	}
	free(p);//最后free那个被删除的节点
	return e;
}
遍历队列
void visit(QElemType elem) {
	printf("%d\t", elem);
}
Status QueueTraverse(LinkQueue Q, void(visit)(QElemType)) {
	printf("队列的所有元素:\n");
	if (Q.rear == Q.front)return -1;//为空时,结束函数
	QueuePtr p = Q.front->next;//用变量记录队头,进行指针滑动遍历
	while(p) {
		visit(p->data);
		p = p->next;//更替p指针
	}
	return 1;
}
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值