# 循环队列的基本原理

在数据类型中,队列与栈是极为相似的,
另外,队列在线性表的范畴之内,但在基本的实现方面却受到限制。
对于顺序队列来说,
顺序队列与顺序栈的基本原则恰恰相反,
顺序队列应满足`先入先出``后入后出`的原则,
此外,通过顺序表实现的顺序队列,
倘若想加入队列只能在队尾加入,
倘如想退出队列只能在队头退出。
但,对于循环的顺序队列来说,
应该要满足存储空间未满就可添加的原则,
因此,倘若想实现循环队列的基本功能,
一是通过设置信标来判断空间是否满;
二是通过减少一位存储空间;

# 循环队列的基本创建

Circle_Queues_.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define MAX_SPACE 8
typedef int Element;
struct Circle_SQ_Pointer
{
	Element* element;
	int head;
	int tail;
};
void Init_Queues(struct Circle_SQ_Pointer* C_P);
void Show_Menu();
void Join_Queues(struct Circle_SQ_Pointer* C_P, Element element);
void Out_Queues(struct Circle_SQ_Pointer* C_P);
void Show_Queues(struct Circle_SQ_Pointer* C_P);
int get_length(struct Circle_SQ_Pointer* C_P);
void Clean_Queues(struct Circle_SQ_Pointer* C_P,int* flag);
void destroy_Space(struct Circle_SQ_Pointer* C_P);
Circle_Queues_functions.c
#include"Circle_Queues_.h"
void Init_Queues(struct Circle_SQ_Pointer* C_P)
{
	C_P->element = (Element*)malloc(sizeof(int) * MAX_SPACE);
	C_P->head = 0;
	C_P->tail = 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 Circle_SQ_Pointer* C_P, Element element)
{	
	assert(NULL != C_P->element);
	if (C_P->head == C_P->tail)
		return;
	
	C_P->element[C_P->tail] = element;
	if ((C_P->tail + 1) % MAX_SPACE != C_P->head)
	{
		printf("%d入队\n", element);
		C_P->tail = (C_P->tail + 1) % MAX_SPACE;
	}
}
void Out_Queues(struct Circle_SQ_Pointer* C_P)
{
	assert(NULL != C_P->element);
	if (C_P->head == C_P->tail)
		return;
	printf("%d出队\n", C_P->element[C_P->head]);
	C_P->head = (C_P->head + 1) % MAX_SPACE;
}
void Show_Queues(struct Circle_SQ_Pointer* C_P)
{
	int i = C_P->head;
	while (i != C_P->tail)
	{
		printf("%d ", C_P->element[i]);
		i = (i + 1) % MAX_SPACE;
	}
}
int get_length(struct Circle_SQ_Pointer* C_P)
{
	int i = C_P->head;
	int counting = 0;
	while (i != C_P->tail)
	{
		i = (i + 1) % MAX_SPACE;
		counting++;
	}
	printf("当前存储空间长度为%d\n", counting);
	return counting;
}
void Clean_Queues(struct Circle_SQ_Pointer* C_P, int* flag)
{
	assert(NULL != C_P->element);
	C_P->head = 0;
	C_P->tail = 0;
	*flag = 0;
}
void destroy_Space(struct Circle_SQ_Pointer* C_P)
{
	assert(NULL != C_P->element);
	free(C_P->element);
	C_P->element = NULL;
}
Circle_Queues_main.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Circle_Queues_.h"
int main()
{
	int option = 0;
	int element = 0;
	int flag = 0;
	struct Circle_SQ_Pointer CQ_P;
	Init_Queues(&CQ_P);
	Show_Menu();
	while (printf("\n选择为>"), scanf("%d", &option), option)
	{
		switch (option)
		{
		case 1:
			printf("入队值为(-1终止)>");
			while (scanf("%d", &element), -1 != element)
			{
				if (!(flag))
				{
					CQ_P.element[CQ_P.head] = element;
					CQ_P.tail++;
					
					flag = 1;
					printf("%d入队\n", element);
					continue;
				}
				Join_Queues(&CQ_P, element);
			}
			break;
		case 2:
			Out_Queues(&CQ_P);
			break;
		case 3:
			Show_Queues(&CQ_P);
			break;
		case 4:
			get_length(&CQ_P);
			break;
		case 5:
			Clean_Queues(&CQ_P,&flag);
			break;
		case 6:
			destroy_Space(&CQ_P);
			break;
		default: printf("超出选择范围\n");
		}
		Show_Menu();
	}
	destroy_Space(&CQ_P);
	return 0;
}