# 链队列的基本原理

在数据类型中,队列与栈是极为相似的,
另外,队列在线性表的范畴之内,但在基本的实现方面却受到限制。
对于链队列来说,
链队列与链栈的基本原则恰恰相反,
链队列应满足`先入先出``后入后出`的原则,
此外,通过链表实现的链队列,
倘若想加入队列只能在队尾加入,
倘如想退出队列只能在队头退出。

# 链队列的基本创建

Link_Queues_.h(头文件)
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define DEBUG
typedef int Element;
struct Link_Node
{
	Element element;
	struct Link_Node* next;
};
struct Link_Queues_Pointer
{
	struct Link_Node* head;
	struct Link_Node* tail;
	int space;
};
void Init_Queues(struct Link_Queues_Pointer* LQ_P);
void Show_Menu();
void Join_Queues(struct Link_Queues_Pointer* LQ_P, Element element);
void Out_Queues(struct Link_Queues_Pointer* LQ_P);
void Show_Queues(struct Link_Queues_Pointer* LQ_P);
int get_length(struct Link_Queues_Pointer* LQ_P);
void Clean_Queues(struct Link_Queues_Pointer* LQ_P);
void destroy_Space(struct Link_Queues_Pointer* LQ_P);
Link_Queues_functions.c
#include"Link_Queues_.h"
void Init_Queues(struct Link_Queues_Pointer* LQ_P)
{
	LQ_P->head = NULL;
	LQ_P->tail = NULL;
	LQ_P->space = 0;
}
void Show_Menu()
{
	printf("\n********************************************\n");
	printf(" [1]Join_Queues ***********[2]Out_Queues   *\n");
	printf(" [3]Show_Queues ***********[4]get_length   *\n");
	printf(" [5]Clean_Queues***********[6]destroy_Space*\n");
	printf(" [0]Exit_system ***********                *");
	printf("\n********************************************\n");
}
void Join_Queues(struct Link_Queues_Pointer* LQ_P, Element element)
{
	struct Link_Node* P_Node = (struct Link_Node*)malloc(sizeof(struct Link_Node));
	P_Node->element = element;
	P_Node->next = NULL;
	if (!(LQ_P->space))
	{
		LQ_P->head = P_Node;
		LQ_P->tail = P_Node;
	}
	else
	{
		LQ_P->tail->next = P_Node;
		LQ_P->tail = P_Node;
	}
#ifdef DEBUG
	printf("%d入队\n", element);
#endif
	++LQ_P->space;
}
void Out_Queues(struct Link_Queues_Pointer* LQ_P)
{
	if (LQ_P->space)
	{
		struct Link_Node* P_Node = LQ_P->head->next;
#ifdef DEBUG
		printf("%d出队\n", LQ_P->head->element);
#endif
		free(LQ_P->head);
		LQ_P->head = P_Node;
		--LQ_P->space;
	}
}
void Show_Queues(struct Link_Queues_Pointer* LQ_P)
{
	if (!(LQ_P->space))
		return;
	else
	{
		struct Link_Node* P_Node = LQ_P->head;
		
		while (P_Node->next)
		{
#ifdef DEBUG
			printf("%d ", P_Node->element);
#endif
			P_Node = P_Node->next;
		}
#ifdef DEBUG
		printf("%d ", P_Node->element);
#endif
	}
}
int get_length(struct Link_Queues_Pointer* LQ_P)
{
	printf("当前存储空间长度为%d\n", LQ_P->space);
	return LQ_P->space;
}
void Clean_Queues(struct Link_Queues_Pointer* LQ_P)
{
	int i = LQ_P->space;
	while (i)
	{
		Out_Queues(LQ_P);
		i--;
	}
}
void destroy_Space(struct Link_Queues_Pointer* LQ_P)
{
	Clean_Queues(LQ_P);
	LQ_P->head = NULL;
	LQ_P->head->next = NULL;
	LQ_P->tail = NULL;
}
Link_Queues_main.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Link_Queues_.h"
int main()
{
	int option = 0;
	int element = 0;
	struct Link_Queues_Pointer LQ_P;
	Init_Queues(&LQ_P);
	Show_Menu();
	while (printf("\n选择为>"), scanf("%d", &option), option)
	{
		getchar();
		switch (option)
		{
		case 1:
			printf("入栈值为(-1终止)>");
			while (scanf("%d", &element), -1 != element)
			{
				Join_Queues(&LQ_P, element);
			}
			break;
		case 2:
			Out_Queues(&LQ_P);
			break;
		case 3:
			Show_Queues(&LQ_P);
			break;
		case 4:
			get_length(&LQ_P);
			break;
		case 5:
			Clean_Queues(&LQ_P);
			break;
		case 6:
			destroy_Space(&LQ_P);
			break;
		default: printf("超出选择范围\n");
		}
		Show_Menu();
	}
	destroy_Space(&LQ_P);
	return 0;
}