桌上有一叠牌,从第一张牌(即位于顶面的牌)开始从上往下依次编号为1~n。当至少还剩三张牌时进行以下操作:把第一、二张牌扔掉,然后把当前状态下新的第一张放到整叠牌的最后。输入n,输出每次扔掉的牌,以及最后剩下的牌。 输入输出样例如下:
输入4
第一次:扔掉1,2
从顶向底最后剩下:4,3
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef int status;
typedef struct Qnode//链表结点
{
ElemType data;//数据域
struct Qnode *next;//指向下一个结点
}Qnode;
typedef struct link_queue//链队
{
Qnode *front,*rear;//链队的头指针和尾指针
int size=0;//链队长度
}Link_Queue;
//1.链队列初始化
status Init_Link_Queue(Link_Queue *Q)
{
Q=(Link_Queue*)malloc(sizeof(Link_Queue));//开辟链队指针结点
if(!Q)
{
printf("初始化链队指针结点失败\n");
exit(0);//初始化链队指针结点失败,退出程序
}
}
//2.初始化
status Init_Qnode(Link_Queue *Q,Qnode *P)
{
P=(Qnode*)malloc(sizeof(Qnode));//开辟头结点
if(!P)
{
printf("初始化头结点失败\n");
exit(0);//初始化头结点失败,退出程序
}
P->next=NULL;//头节点指向空
P->data=0; //头数据域为零
Q->front=Q->rear=P;//将头尾指针指向头链表
}
//3.链队列的扩容操作
status Expansion_Queue(Link_Queue *Q)
{
Qnode *P;
P=(Qnode*)malloc(sizeof(Qnode));//开辟新结点
if(!P)
{
printf("开辟新结点失败\n");
return ERROR;//开辟新结点失败,退出程序
}
Q->rear->next=P;//将新结点挂在链表上
P->next=NULL;//新结点的next指向空
P->data=0;//新结点数据域为零
Q->rear=Q->rear->next;//头指针后移
return OK;
}
//4.链队列的入队操作
status Push_Queue(Link_Queue *Q,ElemType e)
{
if(!Expansion_Queue(Q))//判断是否需要扩容,并扩容
exit(0);
Q->rear->data=e;//将数据放入数据域
Q->size++;//记录存储数据量
return OK;
}
//5.出队列
status Delete_Queue(Link_Queue *Q,ElemType *e)
{
Qnode *p;
if(Q->front==Q->rear)//判断结点是否为空
{
return ERROR;
}
p=Q->front->next;
*e=p->data;//将数据传给*e
Q->front->next=p->next;//头指针后移
if(p==Q->rear)//p和尾指针地址相同时尾指针归零(指向头指针的指向)
Q->rear=Q->front;
free(p);//释放空间
return OK;
}
//6.链队列的撤销
status Destroy_Link_Queue(Link_Queue *Q)//从头开始依次释放
{
Qnode *p,*q;
p=Q->front;
q=p->next;
while(1)
{
if(Q->rear==p)//如果尾指针和p(头指针) 同时指向同一块空间释放掉,直接结束程序
{
free(p);
break;
}
free(p);//释放空间
p=q;//将头指针指向下一个结点
q=q->next;
}
printf("链队列撤销完成");
}
//7.判断
status Judgement_Queue(Link_Queue *Q)
{
Qnode *p;
int i,j=0;
while(Q->size>3)//判断是否剩最后三张牌
{
i=2;
j++;
printf("第%d次撤销",j);
while(i)//两次循环撤掉前两空间
{
p=Q->front->next;//首元节点没有存数据,从下一个结点开始
Q->front->next=p->next;//将指针指向下一个结点
printf(" %d ",p->data);
free(p);
Q->size--; //数据量减少
i--;
}
printf("\n");
Q->rear->next=Q->front->next;//将有数据的第一个结点放到队尾
Q->front->next=Q->front->next->next;
Q->rear=Q->rear->next;
Q->rear->next=NULL;
}
}
int main()
{
Link_Queue Q;//定义头指针结点
Qnode P;//定义存数据结点
ElemType e;
Init_Link_Queue(&Q);//头指针的初始化
Init_Qnode(&Q,&P);//数据指针的初始化
printf("请输入数据\n");
scanf("%d",&e);
for(int i=1;i<=e;i++)//利用循环实现数据的输入
Push_Queue(&Q,i);//调用入队函数
Judgement_Queue(&Q);
while(1)//利用循环实现数据的输出
{
if(!Delete_Queue(&Q,&e))
break;
printf("%d ",e);
}
printf("\n");
Destroy_Link_Queue(&Q);
}