Data structure-queue (C language)

GitHub code download

https://github.com/Kyrie-leon/Data_Structures/tree/main/stack_queue
After mastering the implementation process of the stack ( data structure-stack (C language) ), the implementation of the queue will become very simple

1. The concept and structure of queues

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

Insert picture description here

Second, the realization 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 an array is used , the efficiency of outputting data from the queue at the head of the array will be lower.

Insert picture description here

2.1 Chain structure storage of queue

typedef int QDataType;

//队列的链表
typedef struct QListNode
{
    
    
	struct QListNode* _next;
	QDataType _data;
}QNode;

//队列的结构
typedef struct Queue
{
    
    
	QNode *_front;	//队头
	QNode *_rear;	//队尾
}Queue;

2.2 Initialize the queue

// 初始化队列 
void QueueInit(Queue* pq)
{
    
    
	assert(pq);
	pq->_front = pq->_rear = NULL;	//队头队尾置空即可

}

2.3 Queue at the end of the team

// 队尾入队列 
void QueuePush(Queue* pq, QDataType data)
{
    
    
	assert(pq);
	QNode * newNode = (QNode *)malloc(sizeof(QNode));	//向内存申请一个结点
	//判断是否申请成功
	if (NULL == newNode)
	{
    
    
		printf("申请失败!\n");
		exit(-1);
	}
	//将新节点入到队尾
	newNode->_data = data;	//数据data赋值给新节点	
	newNode->_next = NULL;	//新节点会作为队尾节点,因此对新节点_next置空
	
	if (pq->_front)
	{
    
    
		pq->_rear->_next = newNode;		//队列不为空,队尾结点先链接新结点
		pq->_rear = newNode;	//再将队尾指向新节点	
	}
	else
	{
    
    
		pq->_front = pq->_rear = newNode;	//如果队列为空,则队头队尾都指向新节点
	}
}

2.4 Head out of the queue

// 队头出队列 
void QueuePop(Queue* pq)
{
    
    
	assert(pq);
	assert(pq->_front);	//出队列判断队列是否为空
	QNode* next = pq->_front->_next;	//next保存新队头结点
	free(pq->_front);
	pq->_front = next;
	//出队列后需要判断队列是否为空
	if (NULL == pq->_front)
	{
    
    
		pq->_rear = NULL;	//如果为空,则队尾也为空
	}
}

2.5 Get the head element of the queue

// 获取队列头部元素 
QDataType QueueFront(Queue* pq)
{
    
    
	assert(pq);
	assert(pq->_front);
	return pq->_front->_data;
}

2.6 Get the tail element of the queue

// 获取队列队尾元素 
QDataType QueueBack(Queue* pq)
{
    
    
	assert(pq);
	assert(pq->_rear);
	return pq->_rear->_data;
}

2.7 Get the number of valid elements in the queue

O (n)

// 获取队列中有效元素个数 
int QueueSize(Queue* pq)
{
    
    
	assert(pq);
	int size = 0;
	QNode* cur = pq->_front;
	//遍历一遍链表
	while (cur)
	{
    
    
		size++;
		cur = cur->_next;
	}
	return size;
}

2.8 Check whether the queue is empty, if it is empty, return a non-zero result, if it is not empty, return 0

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* pq)
{
    
    
	assert(pq);
	return pq->_front == NULL ? 1 : 0;
}

2.9 Destroy the queue

// 销毁队列 
void QueueDestroy(Queue* pq)
{
    
    
	assert(pq);
	//从头节点开始遍历每一个节点并free
	QNode* cur = pq->_front;
	while (cur)
	{
    
    
		QNode* next = cur->_next;	//cur指向下一个节点
		free(cur);
		cur = next;
	}
	pq->_front = pq->_rear = NULL;
}

Three, the interface test of the queue

#include "Queue.h"

void TestQueue()
{
    
    
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	QueuePush(&q, 5);
	while (!(QueueEmpty(&q)))
	{
    
    
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	QueueDestroy(&q);
}

int main()
{
    
    
	//TestStack();
	TestQueue();
	system("pause");
	return 0;
}

Insert picture description here

Fourth, the code list

4.1 Queue.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<windows.h>

typedef int QDataType;

//队列的链表
typedef struct QListNode
{
    
    
	struct QListNode* _next;
	QDataType _data;
}QNode;

//队列的结构
typedef struct Queue
{
    
    
	QNode *_front;	//队头
	QNode *_rear;	//队尾
}Queue;

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

4.2 Queue.c

#include "Queue.h"

// 初始化队列 
void QueueInit(Queue* pq)
{
    
    
	assert(pq);
	pq->_front = pq->_rear = NULL;	//队头队尾置空即可

}
// 队尾入队列 
void QueuePush(Queue* pq, QDataType data)
{
    
    
	assert(pq);
	QNode * newNode = (QNode *)malloc(sizeof(QNode));	//向内存申请一个结点
	//判断是否申请成功
	if (NULL == newNode)
	{
    
    
		printf("申请失败!\n");
		exit(-1);
	}
	//将新节点入到队尾
	newNode->_data = data;	//数据data赋值给新节点	
	newNode->_next = NULL;	//新节点会作为队尾节点,因此对新节点_next置空
	
	if (pq->_front)
	{
    
    
		pq->_rear->_next = newNode;		//队列不为空,队尾结点先链接新结点
		pq->_rear = newNode;	//再将队尾指向新节点	
	}
	else
	{
    
    
		pq->_front = pq->_rear = newNode;	//如果队列为空,则队头队尾都指向新节点
	}
}

// 队头出队列 
void QueuePop(Queue* pq)
{
    
    
	assert(pq);
	assert(pq->_front);	//出队列判断队列是否为空
	QNode* next = pq->_front->_next;	//next保存新队头结点
	free(pq->_front);
	pq->_front = next;
	//出队列后需要判断队列是否为空
	if (NULL == pq->_front)
	{
    
    
		pq->_rear = NULL;	//如果为空,则队尾也为空
	}
}
// 获取队列头部元素 
QDataType QueueFront(Queue* pq)
{
    
    
	assert(pq);
	assert(pq->_front);
	return pq->_front->_data;
}

// 获取队列队尾元素 
QDataType QueueBack(Queue* pq)
{
    
    
	assert(pq);
	assert(pq->_rear);
	return pq->_rear->_data;
}

// 获取队列中有效元素个数 
int QueueSize(Queue* pq)
{
    
    
	assert(pq);
	int size = 0;
	QNode* cur = pq->_front;
	//遍历一遍链表
	while (cur)
	{
    
    
		size++;
		cur = cur->_next;
	}
	return size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* pq)
{
    
    
	assert(pq);
	return pq->_front == NULL ? 1 : 0;
}
// 销毁队列 
void QueueDestroy(Queue* pq)
{
    
    
	assert(pq);
	//从头节点开始遍历每一个节点并free
	QNode* cur = pq->_front;
	while (cur)
	{
    
    
		QNode* next = cur->_next;	//cur指向下一个节点
		free(cur);
		cur = next;
	}
	pq->_front = pq->_rear = NULL;
}

4.3 test.c

#include "stack.h"
#include "Queue.h"

void TestStack()
{
    
    
	Stack ps;
	StackInit(&ps);
	StackPush(&ps, 1);
	StackPush(&ps, 2);
	StackPush(&ps, 3);
	StackPush(&ps, 4);
	StackPush(&ps, 5);
	while (!StackEmpty(&ps))
	{
    
    

		printf("%d, %d\n", StackTop(&ps),StackSize(&ps));
		StackPop(&ps);
	}

	
}

void TestQueue()
{
    
    
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	QueuePush(&q, 5);
	while (!(QueueEmpty(&q)))
	{
    
    
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	QueueDestroy(&q);
}

int main()
{
    
    
	//TestStack();
	TestQueue();
	system("pause");
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_40076022/article/details/112306861