[Data structure - C language] Queue (Queue)

Table of contents

1. Queue

1.1 The concept and structure of the queue

2. Implementation of the queue

2.1 Interface

3. Implementation of the interface

3.1 Initialize the queue

3.2 The end of the queue enters the queue

analyze:

3.3 Head out of the queue

analyze:

3.4 Get the head element of the queue

3.5 Get the tail element of the queue

3.6 Get the number of valid elements in the queue

3.7 Check if the queue is empty

3.7.1 Null judgment of int type

3.7.2 bool type null

3.8 Destroy the queue

4. Complete code

5. Effect display


1. Queue

1.1 The concept and structure of the queue

Queue: A special linear table that only allows inserting data at one end and deleting data at the other end. The queue has a first-in-first-out FIFO
(First In First Out) . The end of the delete operation is called the head of the queue

2. Implementation of the queue

Queues can also be implemented in the structure of arrays and linked lists. It is better to use the structure of linked lists, because if the structure of arrays is used,
the efficiency of dequeueing and outputting data at the head of the array will be relatively low. This article is to implement a queue with a linked list.

2.1 Interface

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
// 链式结构:表示队列 
typedef int QDataType;
typedef struct QListNode
{
	struct QListNode* next;
	QDataType data;
}QNode;

// 队列的结构 
typedef struct Queue
{
	QNode* front;
	QNode* rear;
	int size;
}Queue;

// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);

3. Implementation of the interface

3.1 Initialize the queue

We set both the head pointer and the tail pointer to NULL, and assign the size of the queue to 0.

void QueueInit(Queue* q)
{
	assert(q);

	q->front = NULL;
	q->rear = NULL;	
	q->size = 0;
}

3.2 The end of the queue enters the queue

void QueuePush(Queue* q, QDataType data)
{
	assert(q);

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail:");
		return;
	}
	newnode->data = data;
	newnode->next = NULL;

	if (q->rear == NULL)
	{
		assert(q->front == NULL);

		q->front = q->rear = newnode;
	}
	else
	{
		q->rear->next = newnode;
		q->rear = newnode;
	}
	q->size++;
}

analyze:

We implement the queue with a linked list, so we have to malloc a newnode node every time we join the queue, and set newnode->data = data, newnode->next = NULL.

The next step is to connect:

We have to consider whether this node is the first node of the queue.

1. If it is the first node of the queue, we make the head and tail pointers point to this node (q->front = q->rear = newnode);

2. Not the first node of the queue, we assign the next of the tail pointer to a new node (q->rear->next = newnode;), and then let the tail pointer point to the new node (q->rear = newnode;) ;

3. Let the size++ of the queue.

3.3 Head out of the queue

void QueuePop(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));

	//1.一个结点
	if (q->front->next == NULL)
	{
		free(q->front);
		q->front = q->rear = NULL;
	}
	else//2.多个结点
	{
		QNode* next = q->front->next;
		free(q->front);
		q->front = next;
	}
	q->size--;
}

analyze:

When dequeuing, consider whether the queue is a node:

1. There is only one node in the queue. After we release this node (free(q->front)), we empty the head and tail pointers (q->front = q->rear = NULL);

2. There are multiple nodes in the queue, then we save the next node at the head of the queue (next = q->front->next), and then release the head of the queue (free(q->front) ), and finally let the team head point to the next node of the team head before releasing (q->front = next);

3. Finally, let the size of the queue--.

3.4 Get the head element of the queue

When fetching the head element of the queue, we first need to judge the queue as empty. If the queue is empty, there is no head element of the queue.

QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));

	return q->front->data;
}

3.5 Get the tail element of the queue

When fetching elements at the end of the queue, we first need to judge the queue as empty. If the queue is empty, there is no element at the end of the queue.

QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));

	return q->rear->data;
}

3.6 Get the number of valid elements in the queue

When we created the structure of the queue, we created a variable size in it, which specifically records the number of elements in the queue, so here we only need to return q->size. If the size variable is not defined, it is also possible to traverse the queue and use a counter to count the number.

int QueueSize(Queue* q)
{
	assert(q);

	return q->size;
}

3.7 Check if the queue is empty

3.7.1 int type interface

Here we agree that if it is empty, it will return non-zero, and if it is not empty, it will return 0.

int QueueEmpty(Queue* q)
{
	assert(q);

	if (0 == q->size)
		return 1;
	else
		return 0;
}

3.7.2 bool type interface

Directly judge whether the queue head is empty, and the queue is empty if the queue head is empty.

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

	return q->front == NULL;
}

3.8 Destroy the queue

Destroy We've written a lot, so let's get right to it. We first release the singly linked list. There is a point to note here. We need to record the next position first, then release the current position, and then hand over the next position to the current position for iteration. Finally, set the head and tail pointers to NULL, and then set size to 0.

void QueueDestroy(Queue* q)
{
	assert(q);

	QNode* cur = q->front;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	q->front = q->rear = NULL;
	q->size = 0;
}

4. Complete code

The complete code is in the code warehouse, the entry: C language: C language learning code, review more - Gitee.com

5. Effect display

Guess you like

Origin blog.csdn.net/Ljy_cx_21_4_3/article/details/130739681