#include<stdio.h>
#include<stdlib.h>
#define MAX 100
#define TRUE 1
#define FALSE 0
typedef struct Stuck //定义栈
{
int data[MAX]; //存数据
int top;
}Stuck;
typedef struct Node //定义队列
{
int data; //数据域
struct Node* next; //指针域
}LinkQueueNode;
typedef struct
{
LinkQueueNode* front; //头指针
LinkQueueNode* rear; //尾指针
}LinkQueue; //头尾指针封装
int menu_select();
void InitStuck(Stuck* S); //栈的初始化
int InitQueue(LinkQueue* Q); //队列初始化
int IsEmptyStuck(Stuck* S); //判断栈是否为空
int IsEmptyQueue(LinkQueue* Q); //判断队列是否为空
int Push(Stuck* S, int x); //入栈
int Pop(Stuck* S, int* x); //出栈
int EnterQueue(LinkQueue* Q, int x); //入队
int DeleteQueue(LinkQueue* Q, int* x); //出队
void SaveData(LinkQueue* Q, Stuck* S); // 将队列元素存入栈中
void ExitData(LinkQueue* Q, Stuck* S); //将栈中元素返回队列
void Print(LinkQueue* Q); //打印逆置队列元素
void ClearQueue(LinkQueue* Q); //清空队列
void ClearStuck(Stuck* S); //清空栈
int menu_select() //菜单驱动程序
{
int sn;
printf("利用辅助栈进行队列的逆置控制系统\n"); //显示菜单
printf("==============================\n");
printf("1、输入队列元素\n");
printf("2、输出逆置队列\n");
printf("0、退出系统\n");
printf("==============================\n");
printf("请选择0--2:\n");
for (;;) //菜单功能选择
{
scanf("%d", &sn);
getchar();
if (sn < 0 || sn>2)
printf("\n\t输入选择错误,请重新选择0--2:\n");
else
break;
}
return sn;
}
void InitStuck(Stuck* S) //栈初始化
{
S->top = -1;
}
int InitQueue(LinkQueue* Q) //队列初始化
{
Q->front = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
if (Q->front != NULL)
{
Q->rear = Q->front;
Q->front->next = NULL;
return TRUE;
}
else
return FALSE;
}
int EnterQueue(LinkQueue* Q, int x) //入队
{
LinkQueueNode* NewNode;
NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
if (NewNode != NULL)
{
NewNode->data = x;
NewNode->next = NULL;
Q->rear->next = NewNode;
Q->rear = NewNode;
return TRUE;
}
else
return FALSE;
}
int DeleteQueue(LinkQueue* Q, int* x) //出队
{
LinkQueueNode* p;
if (Q->front == Q->rear)
return FALSE;
p = Q->front->next;
Q->front->next = p->next;
if (Q->rear == p)
Q->rear = Q->front;
*x = p->data;
free(p);
return TRUE;
}
int IsEmptyQueue(LinkQueue* Q) //判断队列是否为空
{
if (Q->front == Q->rear)
return TRUE;
else
return FALSE;
}
int IsEmptyStuck(Stuck* S) //判断栈是否为空
{
if (S->top == -1)
return TRUE;
else
return FALSE;
}
int Push(Stuck* S, int x) //压栈
{
if (S->top == MAX - 1)
return FALSE;
S->top++;
S->data[S->top] = x;
return TRUE;
}
int Pop(Stuck* S, int* x) //出栈
{
if (S->top == -1)
return FALSE;
else
{
*x = S->data[S->top];
S->top--;
return TRUE;
}
}
/*
TODO:出队进栈
功能描述:将队列元素存入栈中
参数说明:Q是LinkQueue类型的指针;S是Stuck类型的栈
提示:判断如果队列不为空元素出队,元素进栈
*/
void SaveData(LinkQueue* Q, Stuck* S)// 将队列元素存入栈中
{
LinkQueueNode* p;
while(Q->front != Q->rear)
{
p = Q->front->next;
Q->front->next = p->next;
if (Q->rear == p)
{
Q->rear = Q->front;
}
S->top++;
S->data[S->top] = p->data;
}
}
/*
TODO:出栈进队
功能描述:将栈中元素返回队列
参数说明:Q是LinkQueue类型的指针;S是Stuck类型的栈
提示:如果栈不为空,元素出栈;元素进队
*/
void ExitData(LinkQueue* Q, Stuck* S)//将栈中元素返回队列
{
//S->top--;
while (S->top!=-1)
{
LinkQueueNode* NewNode;
NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
if (NewNode != NULL)
{
NewNode->data = S->data[S->top];
S->top--;
NewNode->next = NULL;
Q->rear -> next = NewNode;
Q->rear = NewNode;
}
}
}
/*
TODO:打印元素
功能描述:打印队列元素
参数说明:Q是LinkQueue类型的指针
提示:将参数p初始化为第一个元素,如果该参数不为空,则使用printf("%3d",p->data)打印元素并将指针后移。
*/
void Print(LinkQueue* Q)//打印逆置队列元素
{
LinkQueueNode* p;
//Q->front = Q->front->next;
p = Q->front->next;
while (p != NULL)
{
printf("%3d", p->data);
p=p->next;
}
}
void ClearQueue(LinkQueue* Q)//清空队列
{
LinkQueueNode* p, * q;
while (Q->front != Q->rear) //如果头尾指针指向同一个结点,即队列不为空
{
p = Q->front; //p指向头结点
while (p->next != Q->rear) //将p指向尾指针指向结点的前一个结点
{
p = p->next;
}
q = p->next; //q指向尾结点
Q->rear = p; //尾指针指向尾结点前一个结点
Q->rear->next = NULL; //将尾指针指针域置为空
free(q); //释放尾结点
}
}
void ClearStuck(Stuck* S)//清空栈
{
S->top = -1;
}
void main()
{
int i, n, x;
LinkQueue Q;
Stuck S;
InitStuck(&S);
InitQueue(&Q);
for (;;) // 无限循环,选择0 退出
{
switch (menu_select()) // 调用菜单函数,按返回值选择功能函数
{
case 1:
printf("输入队列\n");
if (!IsEmptyQueue(&Q))//判断队列是否为空
ClearQueue(&Q);//不是空,清空队列
if (!IsEmptyStuck(&S))//判断栈是否为空
ClearStuck(&S);//不是空,清空栈
printf("请输入队列元素个数:\n");
scanf("%d", &n);
printf("请输入队列元素:\n");
for (i = 1; i <= n; i++)
{
scanf("%d", &x);
EnterQueue(&Q, x);//入队
}
break;
case 2:
printf("输出逆置的队列\n");
SaveData(&Q, &S);//将队列元素存入栈中
ExitData(&Q, &S);//将栈中元素返回队列
Print(&Q);//打印逆置队列元素
printf("\n");
break;
case 0:
printf("再见!\n"); //退出系统
return;
} // switch语句结束
} // for循环结束
} // main()函数结束