Data Structure - Queue (10)

data structure


1. What is a queue

Queue: A special linear table that only allows inserting data at one end and deleting data at the other end. The queue has FIFO (First In First Out).

Enqueue: The end of the insertion operation is called the end of the queue.
insert image description here
Dequeue: The end of the delete operation is called the head of the queue.
insert image description here
Queues are also divided into sequential queues and chained queues

Second, the realization of the queue

1. The structure of the queue

The queue needs to be operated at the head and tail of the queue at the same time, which is implemented here using a linked list.
However, because the linked list is less efficient when accessing the tail of the queue, the tail structure pointer is used to point to the end of the linked list.

typedef int QNDataType;
typedef struct QueueNode//对列结点的结构体
{
    
    
	struct QueueNode* next;
	QNDataType val;
}QueueNode;

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

2. Initialization of the queue

//队列的初始化
void QueueInit(Queue* pq)
{
    
    
	pq->head = NULL;
	pq->tail = NULL;
	printf("队列初始化成功\n"); 
}

insert image description here

3. Join the team

//入队 
void QueuePush(Queue* pq, QNDataType x)
{
    
    
	assert(pq);

	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
    
    
		exit(-1);//创建新结点失败,直接退出
	}
	newnode->val = x;
	newnode->next = NULL;
	
	//队列中一个结点都没有
	if (pq->tail == NULL)
	{
    
    
		//新结点即使队头也是队尾
		pq->head = newnode;
		pq->tail = newnode;
	}
	else
	{
    
    
		//队列中有结点,在队尾插入新结点
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
		printf("%d入队成功\n",x); 
}

insert image description here

4. Dequeue

//出队 
void QueuePop(Queue* pq)
{
    
    
	assert(pq);
//	assert(!QueueEmpty(pq));//没有结点不进行删除操作
	 
	//只有一个结点,删除该结点后将head,tail置空
	if (pq->head->next == NULL)
	{
    
    
		free(pq->head);
		pq->head = NULL;
		pq->tail = NULL; 
		i++;
	}
	//多个结点
	else
	{
    
    
		//保留头结点的下一个结点,下一个结点为新的头
		QueueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
		i++;
	}
		printf("第%d个数出队成功\n",i); 
}

insert image description here
5. Judgment of the queue

//判断队列是否为空
void QueueEmpty(Queue* pq)
{
    
    
	assert(pq);
	//头结点为空则队列为空
	if(pq->head == NULL)
	printf("队列为空\n");
	else
	printf("队列不为空\n"); 
}

//计算队列的结点个数
int QueueSize(Queue* pq)
{
    
    
	int size = 0;
	QueueNode* cur = pq->head;

	while (cur)
	{
    
    
		size++;
		cur = cur->next;
	}

	printf("队列长度为%d\n",size);
}

insert image description here

6. Obtaining the head and tail of the queue

//得到队头的数据
QNDataType QueueFront(Queue* pq)
{
    
    
	assert(pq);
	//assert(!QueueEmpty(pq));
    if(pq->head!=NULL) 
	printf("队头数据为%d\n",pq->head->val);
	else
	printf("无队头");
}

//得到队尾的数据
QNDataType QueueBack(Queue* pq)
{
    
    
	assert(pq);
//	assert(!QueueEmpty(pq));
 if(pq->tail!=NULL) 
		printf("队尾数据为%d\n",pq->tail->val);
			else
	printf("无队尾");
}

insert image description here

Summarize

Attach the full code

 //队列
 #include<stdio.h> 
 #include<assert.h>
 static i=0;
 typedef int QNDataType;
typedef struct QueueNode//对列结点的结构体
{
    
    
	struct QueueNode* next;
	QNDataType val;
}QueueNode;

//队列
typedef struct Queue
{
    
    
	QueueNode* head;//指向队头结点
	QueueNode* tail;//指向队尾结点
}Queue;
//队列的初始化
void QueueInit(Queue* pq)
{
    
    
	pq->head = NULL;
	pq->tail = NULL;
	printf("队列初始化成功\n"); 
}
//入队 
void QueuePush(Queue* pq, QNDataType x)
{
    
    
	assert(pq);

	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
    
    
		exit(-1);//创建新结点失败,直接退出
	}
	newnode->val = x;
	newnode->next = NULL;
	
	//队列中一个结点都没有
	if (pq->tail == NULL)
	{
    
    
		//新结点即使队头也是队尾
		pq->head = newnode;
		pq->tail = newnode;
	}
	else
	{
    
    
		//队列中有结点,在队尾插入新结点
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
		printf("%d入队成功\n",x); 
}
//出队 
void QueuePop(Queue* pq)
{
    
    
	assert(pq);
//	assert(!QueueEmpty(pq));//没有结点不进行删除操作
	 
	//只有一个结点,删除该结点后将head,tail置空
	if (pq->head->next == NULL)
	{
    
    
		free(pq->head);
		pq->head = NULL;
		pq->tail = NULL; 
		i++;
	}
	//多个结点
	else
	{
    
    
		//保留头结点的下一个结点,下一个结点为新的头
		QueueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
		i++;
	}
		printf("第%d个数出队成功\n",i); 
}
//判断队列是否为空
void QueueEmpty(Queue* pq)
{
    
    
	assert(pq);
	//头结点为空则队列为空
	if(pq->head == NULL)
	printf("队列为空\n");
	else
	printf("队列不为空\n"); 
}

//得到队列的结点个数
int QueueSize(Queue* pq)
{
    
    
	int size = 0;
	QueueNode* cur = pq->head;

	while (cur)
	{
    
    
		size++;
		cur = cur->next;
	}

	printf("队列长度为%d\n",size);
}
//得到队头的数据
QNDataType QueueFront(Queue* pq)
{
    
    
	assert(pq);
	//assert(!QueueEmpty(pq));
    if(pq->head!=NULL) 
	printf("队头数据为%d\n",pq->head->val);
	else
	printf("无队头");
}

//得到队尾的数据
QNDataType QueueBack(Queue* pq)
{
    
    
	assert(pq);
//	assert(!QueueEmpty(pq));
 if(pq->tail!=NULL) 
		printf("队尾数据为%d\n",pq->tail->val);
			else
	printf("无队尾");
}

int main()
{
    
    
	
	QueueNode que;
	QueueInit(&que);
	QueuePush(&que,1) ;
	QueuePush(&que,5) ;
	QueueEmpty(&que);
	QueueSize(&que);
	QueueFront(&que);
	QueueBack(&que);
	QueuePop(&que); 
	QueuePop(&que); 
	QueueEmpty(&que);
	QueueSize(&que);
	QueueFront(&que);
	QueueBack(&que);
}

Guess you like

Origin blog.csdn.net/qq_51963216/article/details/128885550