【数据结构】5.1链队列(C语言)

【数据结构】——5.1 链队列

一、队列的概念及结构

1. 队列的概念

​ 队列:只允许在一端进行插入,另一端进行删除的数据操作的特殊线性表,插入的一端叫做队头,删除的一端叫队尾

​ 队列具有先进先出FIFO(First In First Out)的特点

​ 队列的插入叫做入队,删除叫出队列

​ 队列可以分为顺序队列和链队列,由于顺序队列头插需要移动大量元素,时间复杂度高,所以链队列是一个很好的选择,这里我们实现链队列和循环队列

  1. 顺序队列

在这里插入图片描述

  1. 链队列

查看源图像

2. 链队列结构声明

typedef int QDataType;

typedef struct QueueNode	 //队列数据节点
{
    QDataType data;			//数据
    struct QueueNode* next;	 //指向下一个结点的指针
} QueueNode;

typedef struct Queue		//队列
{
    QueueNode* head;		//头指针
    QueueNode* tail;		//尾指针
} Queue;

二、链队列实现

1. 初始化

  1. 为队列申请空间
  2. 初始化头尾指针,都赋值为NULL
void QueueInit(Queue** ppq)
{
	assert(ppq != NULL);
	*ppq = (Queue*)malloc(sizeof(Queue));
	if (*ppq == NULL)
	{
		perror("malloc fail\n");
		exit(-1);
	}

	(*ppq)->head = NULL;
	(*ppq)->tail = NULL;
}

2. 入队列

  1. 先为节点申请空间,并赋值
  2. 入队列前先判断队列是否为空,空队列插入数据时头尾指针都要修改
void QueuePush(Queue** ppq, QDataType x)
{
	assert(ppq != NULL);

	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc fail\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	
	if ((*ppq)->head == NULL)
	{
		(*ppq)->head = newnode;
		(*ppq)->tail = newnode;
	}
	else
	{
		(*ppq)->tail->next = newnode;
		(*ppq)->tail = (*ppq)->tail->next;
	}
}

3. 出队列

  1. 先判读队列是否为空(这里对空队列不做处理)
  2. 若是队列只剩一个节点,则出队列后头尾指针都要修改为NULL
void QueuePop(Queue** ppq)
{
	assert(ppq != NULL);
	
	if (QueueEmpty(*ppq))
	{
		return;
	}

	if ((*ppq)->head == (*ppq)->tail)
	{
		free((*ppq)->head);
		(*ppq)->head = NULL;
		(*ppq)->tail = NULL;
	}
	else
	{
		QueueNode* next = (*ppq)->head->next;
		free((*ppq)->head);
		(*ppq)->head = next;
	}
}

4. 获取队头元素

  1. 队列为空断言处理
  2. 直接返回头指针指向的数据
QDataType QueueFront(Queue* pq)
{
	assert(pq != NULL);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

5. 获取队尾元素

  1. 队列为空断言处理
  2. 直接返回尾指针指向的数据
QDataType QueueBack(Queue* pq)
{
	assert(pq != NULL);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

6. 获取元素个数

​ 遍历队列,使用计数器记录元素个数

size_t QueueSize(Queue* pq)
{
	size_t count = 0;
	QueueNode* cur = pq->head;
	while (cur != NULL)
	{
		count++;
		cur = cur->next;
	}
	return count;
}

7. 判断队列是否为空

​ 若是头指针为NULL,则队列为空

_Bool QueueEmpty(Queue* pq)
{
	return pq->head == NULL;
}

8. 销毁

  1. 遍历队列,依次释放节点
  2. 最后释放队列,并将队列指针置为NULL
void QueueDestroy(Queue** ppq)
{
	assert(ppq != NULL);

	QueueNode* cur = (*ppq)->head;
	while (cur != NULL)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}

	free(*ppq);
	*ppq = NULL;
}

三、完整代码

代码保存在gitee中:点击完整代码参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值