对于循环队列的练习
/**********************************************************
* 对于数据结构中的循环队列的练习
* 本次练习主要是针对王道书上的内容进行简单练习
* 本次练习的主要内容有 队列的初始化操作
* 队列的判空和判断是否满了的操作
* 入队、出队、获取队头元素以及获取队列中的所有的元素
* 注意:本次练习将会采用三种方式来实现队列的判空和判满
* 本次练习依然采用队尾指针指向队尾元素的下一个元素的方式
***********************************************************/
#include "stdlib.h"
#include "stdio.h"
#define MAX_SIZE 10
typedef int ElemType;
typedef struct {
ElemType data[MAX_SIZE];
int front, rear;
} CircleQueue;
void showMenu();
bool initQueue(CircleQueue &circleQueue);
bool isEmptyQueueOne(CircleQueue &circleQueue);
bool isFullQueueOne(CircleQueue &circleQueue);
bool isEmptyQueueTwo(CircleQueue &circleQueue, int &count);
bool isFullQueueTwo(CircleQueue &circleQueue, int &count);
bool isEmptyQueueThree(CircleQueue &circleQueue, int &tag);
bool isFullQueueThree(CircleQueue &circleQueue, int &tag);
bool enQueue(CircleQueue &circleQueue,int value);
bool outQueue(CircleQueue &circleQueue, int &outValue);
bool getTopValue(CircleQueue &circleQueue,int &topValue);
void getValues(CircleQueue &circleQueue);
int main() {
bool isExit = false;
//定义队列
CircleQueue circleQueue;
while (!isExit) {
showMenu();
int option;
scanf("%d", &option);
switch (option) {
case 1:
//初始化队列
if (initQueue(circleQueue)) {
printf("初始化队列成功\n");
}
break;
case 2:
//判断队列是否为空
if(isEmptyQueueOne(circleQueue)){
printf("当前队列为空\n");
}else{
printf("当前队列非空\n");
}
break;
case 3:
//入队
printf("请输入要入队的元素");
int value;
scanf("%d", &value);
if(enQueue(circleQueue,value)){
printf("入队成功\n");
}else{
printf("入队失败\n");
}
break;
case 4:
//出队
int outValue;
if(outQueue(circleQueue,outValue)){
printf("出队成功 %d\n",outValue);
}else{
printf("出队失败\n");
}
break;
case 5: {
//获取队头元素
int topValue;
if(getTopValue(circleQueue,topValue)){
printf("队头元素为 %d\n",topValue);
}else{
printf("获取队头元素失败\n");
}
break;
}
case 6:
//获取队中的所有的元素
getValues(circleQueue);
break;
case 7:
isExit = true;
break;
default:
printf("输入错误请重新输入\n");
break;
}
}
}
/**
* 查看当前队列中的所有的元素
*/
void getValues(CircleQueue &circleQueue){
if(!isEmptyQueueOne(circleQueue)){
printf("当前队列中的元素为 ");
for (int i = circleQueue.front; i < circleQueue.rear; ++i) {
printf(" %d",circleQueue.data[i]);
}
printf("\n");
}
}
/**
* 查看对头的元素
*/
bool getTopValue(CircleQueue &circleQueue,int &topValue){
if(isEmptyQueueOne(circleQueue)){
//队列为空
return false;
}
topValue = circleQueue.data[circleQueue.front];
return true;
}
/**
* 出队操作
* 在进行出队操作的时候同样的需要考虑队列当前的存储情况
* 如果队列为空的情况下则是不能够进行出队的操作
* 当且仅当队列不为空的时候进行出队的操作
* 同样的需要注意队头指针的移动 不再是 front++
* 而是通过取余操作的进行队头指针的移动
*/
bool outQueue(CircleQueue &circleQueue, int &outValue){
if(!isFullQueueOne(circleQueue)){
//队列不没有满,则进行入队的操作
outValue = circleQueue.data[circleQueue.front];
circleQueue.front = (circleQueue.front + 1) % MAX_SIZE;
return true;
}
//队列已经满了则进行出队
return false;
}
/**
* 入队操作
* 注意:在进行入队操作的时候
* 同样的需要对队列的存储情况进行判断
* 当队列满了的时候不能进行入队的操作
* 当队列没有满了的情况下可以进行入队的操作
*
* 对于队尾指针的移动同样也需要注意
* 不再是以往的rear++的形式
* 而是通过取余操作来移动队尾指针
*/
bool enQueue(CircleQueue &circleQueue,int value){
if(!isFullQueueOne(circleQueue)){
//队列没有满,进行入队的操作
circleQueue.data[circleQueue.rear] = value;
circleQueue.rear = (circleQueue.rear + 1 ) % MAX_SIZE;
return true;
}
//队列满了
return false;
}
/**
* 判断队列是否为空和是否满了
* 第一种方式:通过牺牲一个存储单元
* 判断条件:队空 rear == front
* 队满 front = (rear + 1) % MAX_SIZE
*/
bool isEmptyQueueOne(CircleQueue &circleQueue) {
if (circleQueue.front == circleQueue.rear) {
return true;
}
return false;
}
bool isFullQueueOne(CircleQueue &circleQueue) {
if (circleQueue.front == (circleQueue.rear + 1) % MAX_SIZE) {
return true;
}
return false;
}
/**
* 判断队列时空还是满了
* 第二种方式:设置一个计数器count,用来计算当前队列中的元素的个数
* 出队时 count-- 入队时 count++
* 通过判断count的数量来判断队列的存储情况
* 这就需要设置全局变量count
* 并且在出队和入队时使用count
* 下面给出判断实列
*/
bool isEmptyQueueTwo(CircleQueue &circleQueue, int &count) {
if (count == 0) {
return true;
}
return false;
}
bool isFullQueueTwo(CircleQueue &circleQueue, int &count) {
if (count == MAX_SIZE) {
return true;
}
return false;
}
/**
* 判断队空还是队满
* 第三种方式:增加tag标识符
* 当头指针和为指针指向同一个位置时
* 通过判断tag来获取是出队信息还是入队信息
* 其中 tag = 0 代表出队
* tag = 1 代表入队
* 如果时出队导致的front == rear,则表明时当前队列一空
* 如果是入队时导致front == rear,则表明队列满了
*/
bool isEmptyQueueThree(CircleQueue &circleQueue, int &tag) {
if(circleQueue.front == circleQueue.rear && tag == 0){
return true;
}
return false;
}
bool isFullQueueThree(CircleQueue &circleQueue, int &tag) {
if(circleQueue.front == circleQueue.rear && tag == 1){
return true;
}
return false;
}
/**
* 初始化循环队列
* 在初始化队列的过程中,一定将循环队列的队头和对队尾
* 都指向数组的开始位置
*/
bool initQueue(CircleQueue &circleQueue) {
circleQueue.rear = circleQueue.front = 0;
return true;
}
void showMenu() {
printf(" 对于循环队列的操作\n");
printf("1 初始化队列\n");
printf("2 判断队列是否为空\n");
printf("3 入队\n");
printf("4 出队\n");
printf("5 获取对头元素\n");
printf("6 获取队列中的所有的元素\n");
printf("请输入你的选择 ");
}