Wangdao postgraduate entrance examination data structure--4.3 chain queue

Table of contents

foreword

1. Definition of chain queue

2. The structure of the chain queue

3. Chain queue operation

3.1 Define the chain queue

3.2 Initialization

3.3 Joining the team

3.4 Dequeue

3.5 Traverse to find table length

3.6 Empty, destroy

4. Complete code


foreword

Date: 2023.7.25

Book: 2024 Data Structure PubMed Review Guide (Wang Dao PubMed Series)

Content: Realize the basic implementation of sequential queues, the main functions are as follows:
1. Data structure of chain queues
2. Entering the queue
3. Exiting the queue
4. Traversing
5. Asking for the captain

6. Empty, destroy

1. Definition of chain queue

First of all, let's take a look at what is a queue? A queue is a first-in-first-out (FIFO) linear list that only allows insertion at one end of the list and deletion at the other end. This is consistent with the queuing in our daily life, the element that enters the queue first leaves first. The structure diagram of the queue is as follows:

       After understanding the queue, the chain queue is very simple, and the queue represented by the linked list is simply called the chain queue. A chain queue obviously needs two pointers indicating the head and tail of the queue (referred to as head pointer and tail pointer respectively) to be uniquely determined.


2. The structure of the chain queue

3. Chain queue operation

3.1 Define the chain queue

//1.定义一个链队列
//队列的节点类型
typedef struct  LinkNode{
    ElemType data;//数据域
    struct LinkNode *next;//指针域
}LinkNode;
//链式队列管理结构
typedef struct LinkQueue{
    LinkNode *front;  //队头指针
	LinkNode *rear;   //队尾指针
}LinkQueue;

 3.2 Initialization

//2.初始化
//初始化队列
void InitQueue(LinkQueue *Q){
	//申请头结点内存空间
	LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
	
	//初始化时,将头指针和尾指针都指向头结点
	Q->front = Q->rear = s;
	//将头结点的下一结点赋空
	Q->rear->next = NULL;
}

3.3 Joining the team

//3.入队
//在队尾执行插入操作
//入队操作:在队尾执行插入操作
void EnQueue(LinkQueue *Q, ElemType x){
	//申请队列结点
	LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
	
	//为申请的队列结点赋值
	s->data = x;
	s->next = NULL;
	//将申请的队列结点插入到队尾
	Q->rear->next = s;
	//更改队列管理结点中尾指针的指向
	Q->rear = s;
}

3.4 Dequeue

//4.出队
//出队操作:删除队头的第一个有效结点
int DeQueue(LinkQueue *Q,ElemType *x){
	//如果队中无有效结点,无需进行操作
	if(Q->front == Q->rear)
		return 0;
	
	//获取队头的第一个有效结点
	LinkNode *p = Q->front->next;
	//将队头的第一个有效结点从队列中断开
    x=p->data;
	Q->front->next = p->next;
	//释放该结点
	free(p);
	//如果删除的结点是最后一个有效结点,需要更改尾指针的指向
	if(p == Q->rear)
		Q->rear = Q->front;
    return 1;
}

3.5 Traverse to find table length

//5.遍历
//打印队列内的数据
void ShowQueue(LinkQueue *Q){
	//获取队列中第一个有效结点
	LinkNode *p = Q->front->next;
	printf("Front:>");
	//将队列中每个有效结点中的数据打印
	while(p != NULL){
		printf("%d ",p->data);
		p = p->next;
	}
	printf("<:rear.\n");
}

//6.求队长
//求队列的长度
int Length(LinkQueue *Q){
	int len = 0;//初始长度为0
	//获取队头的第一个有效结点
	LinkNode *p = Q->front->next;
	//遍历队列,获取一个结点,将队列长度加一
	while(p != NULL){
		len++;
		p = p->next;
	}
	//返回长度值
	return len;
}

3.6 Empty, destroy

//7.清空,销毁
//清空队列:释放所有的有效结点
int ClearQueue(LinkQueue *Q){
	//如果队中无有效结点,无需进行操作
	if(Q->front == Q->rear)
		return 0;
	//获取队头的第一个有效结点
	LinkNode *p = Q->front->next;
	//遍历队列中的有效结点
	while(p != NULL){
		//移除结点
		Q->front->next = p->next;
		//释放结点
		free(p);
		//指向下一个结点
		p = Q->front->next;
	}
	Q->rear = Q->front;
}
//销毁队列
void DestroyQueue(LinkQueue *Q){
	//清空队列
	ClearQueue(Q);
	//释放头结点
	free(Q->front);
	//将管理结点中的头指针和尾指针都指向空
	Q->front = Q->rear = NULL;
}

4. Complete code

#include <stdio.h>
#include <stdlib.h>

#define ElemType int

//1.定义一个链队列
//队列的节点类型
typedef struct  LinkNode{
    ElemType data;//数据域
    struct LinkNode *next;//指针域
}LinkNode;
//链式队列管理结构
typedef struct LinkQueue{
    LinkNode *front;  //队头指针
	LinkNode *rear;   //队尾指针
}LinkQueue;

//2.初始化
//初始化队列
void InitQueue(LinkQueue *Q){
	//申请头结点内存空间
	LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
	
	//初始化时,将头指针和尾指针都指向头结点
	Q->front = Q->rear = s;
	//将头结点的下一结点赋空
	Q->rear->next = NULL;
}

//3.入队
//在队尾执行插入操作
//入队操作:在队尾执行插入操作
void EnQueue(LinkQueue *Q, ElemType x){
	//申请队列结点
	LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
	
	//为申请的队列结点赋值
	s->data = x;
	s->next = NULL;
	//将申请的队列结点插入到队尾
	Q->rear->next = s;
	//更改队列管理结点中尾指针的指向
	Q->rear = s;
}

//4.出队
//出队操作:删除队头的第一个有效结点
int DeQueue(LinkQueue *Q,ElemType *x){
	//如果队中无有效结点,无需进行操作
	if(Q->front == Q->rear)
		return 0;
	
	//获取队头的第一个有效结点
	LinkNode *p = Q->front->next;
	//将队头的第一个有效结点从队列中断开
    x=p->data;
	Q->front->next = p->next;
	//释放该结点
	free(p);
	//如果删除的结点是最后一个有效结点,需要更改尾指针的指向
	if(p == Q->rear)
		Q->rear = Q->front;
    return 1;
}

//5.遍历
//打印队列内的数据
void ShowQueue(LinkQueue *Q){
	//获取队列中第一个有效结点
	LinkNode *p = Q->front->next;
	printf("Front:>");
	//将队列中每个有效结点中的数据打印
	while(p != NULL){
		printf("%d ",p->data);
		p = p->next;
	}
	printf("<:rear.\n");
}

//6.求队长
//求队列的长度
int Length(LinkQueue *Q){
	int len = 0;//初始长度为0
	//获取队头的第一个有效结点
	LinkNode *p = Q->front->next;
	//遍历队列,获取一个结点,将队列长度加一
	while(p != NULL){
		len++;
		p = p->next;
	}
	//返回长度值
	return len;
}
//7.清空,销毁
//清空队列:释放所有的有效结点
int ClearQueue(LinkQueue *Q){
	//如果队中无有效结点,无需进行操作
	if(Q->front == Q->rear)
		return 0;
	//获取队头的第一个有效结点
	LinkNode *p = Q->front->next;
	//遍历队列中的有效结点
	while(p != NULL){
		//移除结点
		Q->front->next = p->next;
		//释放结点
		free(p);
		//指向下一个结点
		p = Q->front->next;
	}
	Q->rear = Q->front;
}
//销毁队列
void DestroyQueue(LinkQueue *Q){
	//清空队列
	ClearQueue(Q);
	//释放头结点
	free(Q->front);
	//将管理结点中的头指针和尾指针都指向空
	Q->front = Q->rear = NULL;
}

void main(){
	LinkQueue Q;
	InitQueue(&Q);//初始化队列
	
	for(int i=1; i<=10; ++i){
		EnQueue(&Q,i);//入队操作
	}
	ShowQueue(&Q);
    int x;
	DeQueue(&Q,&x);
	DeQueue(&Q,&x);
	ShowQueue(&Q);
	printf("Len = %d\n",Length(&Q));
}

 

Guess you like

Origin blog.csdn.net/qq_58602552/article/details/131923994