数据结构-队列

目录

一、定义

二、程序实现

1、结构体声明

2、队列初始化及插入元素

3、删除数据

4、释放空间


一、定义

队列:只允许在一端插入数据,在另一端删除数据操作的特殊线性表,队列具有先进先出的特性。

入队列:进行插入操作的一端称为队尾

出队列:进行删除操作的一端称为队头

 

在实现队列时,使用单链表实现较为合适。

首先,如果使用数组实现,在队首出队后,后面数据需要依次前移,如果数据多,效率会很低。

使用单链表,在队首出队后,只需要将队首指针再指向原先队首元素指向的下一个数据,操作方便。

 

二、程序实现

1、结构体声明

同样,队列的实现也依赖结构体。不同于栈的结构体,队列结构体内只需要两个数据成员,一个是指向队列头部的队头指针,一个是指向最后一个元素的队尾指针。根据这两个指针执行插入删除操作。

typedef struct Queue{
	QueueNode* head;
	QueueNode* tail;
}Queue;

同时,队列元素因为是单链表,因此定义结点的结构体。数据空间与指向下一数据元素的指针。

typedef struct QueueNode{
	DataType data;
	struct QueueNode* next;
}QueueNode;

2、队列初始化及插入元素

队列初始化:因最初队列内无数据,队头指针、队尾指针无数据可指向。因此将对头指针、队尾指针指向NULL。

void QueueInit(Queue* ps)
{
	ps->head=ps->tail=NULL;
}

数据元素初始化:在数据插入时进行初始化。在插入时,先利用malloc函数,开辟一个数据元素空间结点,将data设为要求的数据,naxt指向NULL。然后,队列的头、尾指针需要与插入的结点连接。此时需要分析情况。

①如果队列头指针为NULL,说明此前队列内数据为空,队尾指针同样为NULL,插入新结点后仍然只有一个结点,因此头、尾指针均指向插入结点。

②若队列头指针不为NULL,说明队列至少存在一个元素。此时头指针不需要指向新插入结点。但是尾指针需要指向新插入结点。先通过尾指针的next,将链表链接上插入结点,再将尾指针的值设为插入结点的地址。

 

void QueuePush(Queue* ps,DataType data)
{
	QueueNode* newone=(QueueNode*)malloc(sizeof(QueueNode));
	if(newone==NULL){
		printf("队列扩容失败");
		exit(-1);
	}else{
		newone->data=data;
		newone->next=NULL;
		if(ps->head==NULL){
			ps->head=ps->tail=newone;
		}
		else{
			ps->tail->next=newone;//将链表最后一个结点链接上新插入结点
			ps->tail=newone;//将尾指针的值设为新插入结点地址
		}
	}
}

3、删除数据

删除数据时,同样需要分情况处理。①只有一个数据,删除后头、尾指针均需要指向NULL。②如果有多个数据,尾指针不动,头指针需要指向下一个数据,再free删除的数据的空间。先将要删除的结点的下一个结点的地址保存下来(如果先free的话,第二个结点的地址就找不到了),再free第一个结点。ps->head是当前头结点地址,ps->head->next是第二个结点地址。

void QueuePop(Queue* ps)
{
	assert(ps);
	assert(ps->head);
	if(ps->head->next==NULL){
		free(ps->head);
		ps->head=ps->tail=NULL;
	}else{
		QueueNode* temp=ps->head->next;//先将要删除的结点的下一个结点的地址保存下来。ps->head是当前头结点地址,ps->head->next是第二个结点地址。
		free(ps->head);释放第一个结点空间
		ps->head=temp;	//将头指针的值设为原先的第二个结点地址
	}		
}

4、释放空间

在释放队列时,需要遍历队列内每一个结点,依次释放。定义一个当前结点指针cur,先通过cur->next保存下一节点地址,再释放cur指向的空间。当cur为NULL时结束。然后再将队列的头、尾指针指向NULL。

void QueueDestory(Queue* ps)
{
	assert(ps);
	QueueNode* cur=ps->head;
	while(cur){
		QueueNode* temp=cur->next;
		free(cur);
		cur=temp;
	}
	ps->head=ps->tail=NULL;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值