数据结构队列

数据结构队列

  • 队列的概念及结构
  • 队列的是实现
    • 数据结构
    • 函数接口
    • 初始化
    • 销毁
    • 入队列(尾插)
    • 出队列(头删)
    • 求队列的长度
    • 判断队列是否为空
    • 取队头的数据
    • 取队尾的数据

队列的概念及结构

队列之允许在一段及进行数据插入操作,在另一端进行数据的删除操作的特殊线性表。队列具有先进先出(First In First Out)的特性
进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头
数据结构队列_第1张图片

队列的是实现

队列用数组和链表都可以实现,使用链表的结构实现更优一点,因为如果使用数组的结构,出队列在数组头上出数据,效率比较低。

数据结构

我们选择用链表实现,首先创建一个节点结构体QueueNode,在创建一个结构体来存队列的头节点指针和尾节点指针,这样入队和出队的效率会大大提高。
定义一个整型变量Size来存放队列的长度
代码:

typedef int QDataType;//数据类型

typedef struct QueueNode
{
	struct Queue* next;//下一个节点
	QDataType data;//数据
}QNode;

typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

函数接口

void QueueInit(Queue* pq);//初始化
void QueueDestroy(Queue* pq);//销毁
void QueuePush(Queue*pq,QDataType x);//插入
void QueuePop(Queue* pq);//删除
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);//判断队列是否为空
QDataType QueueFront(Queue* pq); 
QDataType QueueBack(Queue* pq);

初始化

空队列的头和尾节点都是NULL,比较简单
代码:

void QueueInit(Queue* pq)//初始化
{
	assert(pq);
	
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

销毁

直接逐步遍历链表然后逐步free
代码:

void QueueDestroy(Queue* pq)//销毁
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;//防止野指针的生成
	pq->size = 0;
}

入队列(尾插)

数据结构队列_第2张图片
队列的性质是先进先出,所以入队就是尾插,那么就简单了
1.只要是插入就要判断队列是否为空,若为空就需要改变头指针,让头指针指向新节点。
2.不为空直接将尾指针指向的节点连接新节点即可。
代码:

void QueuePush(Queue* pq,QDataType x)//插入(尾插)
{
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc\n");
		return;
	}

	newnode->data = x;//数据的写入
	newnode->next = NULL;//因为是尾插 所以尾指针为NULL

	if (pq->head == NULL)//如果插入前队列为空
	{
		assert(pq->tail == NULL);//如果head为空 tail不为空就有问题
		pq->head = pq->tail = newnode;
	}
	else //插入前队列不为空
	{
		pq->tail->next = newnode;
		pq->tail = pq->tail->next;//尾节点向后遍历
	}
		pq->size++;
}

出队列(头删)

数据结构队列_第3张图片
出队列就相当于链表的头删,
1.头删要排除空队列的情况。
2.需要创建临时变量
3.当队列有一个元素的时候,删除后head为NULL但是tail为野指针,所以tail也需要置空。
代码:

void QueuePop(Queue* pq)//删除(头删)
{
	
	assert(pq);
	assert(pq->head);//空队列不能删除

	QNode* cur = pq->head;
	pq->head = pq->head->next;
	free(cur);
	cur = NULL;
	pq->size--;
	if (pq->head  == NULL)//队列中只有一个元素删除了之后 head为NULL,但是此时tail为野指针
	{
		pq->tail = NULL;
	}
}

求队列的长度

int QueueSize(Queue* pq)//求队列的长度
{
	assert(pq);

	return pq->size;
}

判断队列是否为空

bool QueueEmpty(Queue* pq)//判断队列是否为空
{
	assert(pq);

	return pq->size == 0;
}

取队头的数据

QDataType QueueFront(Queue* pq)//取队头的数据
{
	assert(pq);
	assert(!QueueEmpty(pq));//队列不为空

	return pq->head->data;
}

取队尾的数据

QDataType QueueBack(Queue* pq) //取队尾的数据
{

	assert(pq);
	assert(!QueueEmpty(pq));//队列不为空

	return pq->tail->data;
}

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