链队列的基本操作-C语言

版权声明:Sock的blog, 可以偷看但不可以偷走哦 https://blog.csdn.net/qq_42957923/article/details/85338784

链队列

用链表实现队列的基本操作, 定义两个指针, 分别指向链表的头结点和尾节点, 即作为队列的头和尾, 在队尾进行插入操作, 在对头进行出队操作

具体实现

定义一个链队列

//定义一个队列
typedef int ElemType;
//链表的定义
typedef struct QNode {
	ElemType data;
	struct QNode* next;
}QNode, *QueuePtr;
//队头和队尾指针的定义
typedef struct {
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

初始化链队列

//队列的初始化
void InitQueue(LinkQueue* L) {
	L->front = (QueuePtr)malloc(sizeof(QNode));
	if (!L->front) {
		exit(0);
	}
	L->rear = L->front;
	L->front->next = NULL;
}

链队列的入队操作

//入队列操作
int InQueue(LinkQueue* L, ElemType e) {
	QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
	if (!p) {
		exit(0);
	}
	p->data = e;
	//从队尾入队, 其下一个结点为NULL
	p->next = NULL;
	//连接队列
	L->rear->next = p;
	//调整队尾指针, 使其始终指向队尾
	L->rear = p;
	return 1;
}

链队列的出队操作

//出队列操作
int OutQueue(LinkQueue* L, int* e) {
	if (L->front == L->rear) {
		//printf("队列为空\n");
		return 0;
	}
	//定义一个调整指针来保存被释放的结点, 即队头的下一个元素
	QueuePtr adjust = L->front->next;
	//保存要出队的值
	*e = adjust->data;
	//如果出队后队列为空, 调整尾指针
	if (L->rear == L->front->next) {
		L->rear = L->front;
	}
	//连接队列
	L->front->next = adjust->next;
	free(adjust);
	return 1;
}

队列的销毁

void destroyQueue(LinkQueue* L) {
	while (L->front) {
		//队尾指针始终指向队头指针的下一个元素
		L->rear = L->front->next;
		//释放队头结点
		free(L->front);
		//调整队头位置
		L->front = L->rear;
	}
	//销毁后, 队头和队尾指针都为NULL
}

队列的清空

//清空一个队列
void ClearQueue(LinkQueue* L) {
	//先将队尾指针指向队头指针的下一个结点
	L->rear = L->front->next;
	while (L->front->next) {
		//队尾指针后移
		L->rear = L->rear->next;
		//释放队头指针和队尾指针中间的结点
		free(L->front->next);
		//连接队列
		L->front->next = L->rear;
	}
	//队列为空时, 调整队尾指针
	L->rear = L->front;
}

测试

#include <stdio.h>
#include <windows.h>
/*
	用动态链表实现一个链队列
*/

//定义一个队列
typedef int ElemType;
//链表的定义
typedef struct QNode {
	ElemType data;
	struct QNode* next;
}QNode, *QueuePtr;
//队头和队尾指针的定义
typedef struct {
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

//队列的初始化
void InitQueue(LinkQueue* L) {
	L->front = (QueuePtr)malloc(sizeof(QNode));
	if (!L->front) {
		exit(0);
	}
	L->rear = L->front;
	L->front->next = NULL;
}

//入队列操作
int InQueue(LinkQueue* L, ElemType e) {
	QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
	if (!p) {
		exit(0);
	}
	p->data = e;
	//从队尾入队, 其下一个结点为NULL
	p->next = NULL;
	//连接队列
	L->rear->next = p;
	//调整队尾指针, 使其始终指向队尾
	L->rear = p;
	return 1;
}

//出队列操作
int OutQueue(LinkQueue* L, int* e) {
	if (L->front == L->rear) {
		//printf("队列为空\n");
		return 0;
	}
	//定义一个调整指针来保存被释放的结点, 即队头的下一个元素
	QueuePtr adjust = L->front->next;
	//保存要出队的值
	*e = adjust->data;
	//如果出队后队列为空, 调整尾指针
	if (L->rear == L->front->next) {
		L->rear = L->front;
	}
	//连接队列
	L->front->next = adjust->next;
	free(adjust);
	return 1;
}

void destroyQueue(LinkQueue* L) {
	while (L->front) {
		//队尾指针始终指向队头指针的下一个元素
		L->rear = L->front->next;
		//释放队头结点
		free(L->front);
		//调整队头位置
		L->front = L->rear;
	}
	//销毁后, 队头和队尾指针都为NULL
}

//清空一个队列
void ClearQueue(LinkQueue* L) {
	//先将队尾指针指向队头指针的下一个结点
	L->rear = L->front->next;
	while (L->front->next) {
		//队尾指针后移
		L->rear = L->rear->next;
		//释放队头指针和队尾指针中间的结点
		free(L->front->next);
		//连接队列
		L->front->next = L->rear;
	}
	//队列为空时, 调整队尾指针
	L->rear = L->front;
}

int main(){
	LinkQueue L1;
	InitQueue(&L1);
	for (int i = 0; i < 5; ++i) {
		if (InQueue(&L1, i + 1));
	}
	int e = 0;
	for (int i = 0; i < 5; ++i) {
		if (OutQueue(&L1, &e)) {
			printf("%d ", e);
		}
	}
	printf("\n");
	destroyQueue(&L1);
	if (!L1.front) {
		printf("OK\n");
	}
	system("pause");
	return 0;
}

效果图
在这里插入图片描述

希望本篇文章能对大家有所帮助, 真诚接受大家的评论和建议

猜你喜欢

转载自blog.csdn.net/qq_42957923/article/details/85338784