敢死队问题c语言作业

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
//循环单链表
typedef struct node
{
	int data;
	struct node *next ;
}LNode;//定义节点类型
LNode *CREAT(int n)//创建循环单链表
{
	LNode *s,*q,*T;
	int i;
	if(n!=0)
	{
		T=q=(LNode *)malloc(sizeof(LNode));//生成第一个节点
		q->data=1;//使其data值为1
		for(i=2;i<=n;i++)
		{
			s=(LNode*)malloc(sizeof(LNode));//自动生成节点
			q->next=s;
			q->next->data=i;//赋值
			q=q->next;
		}	
		q->next=T;
	}
	return T;//返回头结点,形成循环链表
}
DELETE (LNode *T)//链表的删除
{
	LNode *a;
	int i;
	while(T->next!=T)
	{
		for(i=1;i<4;i++)//查找要删除节点的前一个节点
			T=T->next;
		a=T->next;
		T->next=a->next;//删除数据
		free(a);
		T=T->next ;
	}
	printf("\n");
	return (T->data );
}
//线性表
#define LIST_INIT_SIZE 100
#define LISTINCCREMENT 10
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef struct KList //定义数据结构体类型
{
	ElemType *elem;//储存空间基址
	int length ; //当前长度
	int listsize;//当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;
int InitList_Sq(SqList &L)//创建线性表函数
{
	L.elem=(ElemType *)malloc(LIST_INIT_SIZE *sizeof(ElemType));
	if(!L.elem)
	{
		printf("存储分配失败");
		return ERROR;
	}
	else
	{
		L.length=0;//空表长度为0
		L.listsize=LIST_INIT_SIZE;
		return OK;//初始存储容量
	}
}
int ListInsert_Sq(SqList &L)//线性表再分配函数
{
	//SqList L;
	int *newbase;
	newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCCREMENT)*sizeof(ElemType));
	//为顺序表增加一个大小为存储LISTNCCREMENT 个数据元素的空间
	if(!newbase)
	{
		printf("存储分配失败");
		return ERROR;
	}
	else
	{
		L.elem=newbase;//新基址
		L.listsize+=LISTINCCREMENT;
		//增加存储容量
		return OK;
	}
}
//循环队列
#define QueueSize 1000//假定预分配的队列空间最多为1000个元素
//typedef int DataType;//假定队列元素的数据类型为字符
typedef struct{
	int data[QueueSize];
	int front;//头指针
	int rear;//尾指针
	int count; //计数器,记录队中元素总数
}CirQueue;

// 置队列空
void Initial(CirQueue *Q)
{//将顺序队列置空
	Q->front=Q->rear=0;
	Q->count=0; //计数器置0
}

// 判队列空
int IsEmpty(CirQueue *Q)
{
	return Q->front==Q->rear;
}

//判队列满
int IsFull(CirQueue *Q)
{
	return Q->rear==QueueSize-1+Q->front;
}

//进队列
void EnQueue(CirQueue *Q,int x)
{
	if (IsFull(Q))
	{
		printf("队列上溢"); //上溢,退出运行
		exit(0);
	}
	Q->data[Q->rear]=x; //新元素插入队尾
	Q->rear=(Q->rear+1)%QueueSize; //循环意义下将尾指针加1
	Q->count ++; //队列数加1
}

//出队列
int DeQueue(CirQueue *Q)
{
	int temp;
	if(IsEmpty(Q))
	{
		printf("队列为空"); //队列空,退出运行
		exit(0);
	}
	temp=Q->data[Q->front];
	Q->front=(Q->front+1)%QueueSize; //循环意义下的头指针加1
	Q->count--; //队列数减1
	return temp;
}
void main()
{
	SqList L;
	int s,i,count=0;//声明变量
	LNode *p;
	int z ,y,e=1,c=1;
	int num;
	int opt;
	while(c)
	{
	printf("1.循环链表\n");
	printf("2.线性表\n");
	printf("3.循环队列\n");
	printf("4.退出\n");
	printf("请选择使用的存储结构:(1~4)\n\n");
	scanf("%d",&opt);
	if(opt >4||opt <1)
	{
		printf("输入有误请重新输入\n");
		continue;
	}
	switch(opt)
	{
	case 1:
		e=1;
		printf("您使用的是循环链表存储结构\n");
		while(e)
		{
			printf("请输入敢死队的人数:\n");
			scanf("%d",&num);
			if(num<1)
			{
				printf("输入有误重新输入\n");
				continue;
			}
			else
			{
				p=CREAT(num);
				y=DELETE(p);//计算从根节点出发剩下的y
				z=num-y+2;//计算从谁出发剩下根节点,公式1+num-y+1
				if(z%num==0)
					printf("从第%d号开始计数能让排长最后一个留下。\n",z);
				else
					printf("从第%d号开始计数能让排长最后一个留下。\n",(num-y+2)%num);
			}
			break;
		}
		break;
	
	case 2:
		printf("您使用的是线性表存储结构\n\n");
		while(e)
		{
			printf("请输入敢死队的人数:\n");
			scanf("%d",&num);
			if(num<1)
			{
				printf("输入有误请重新输入\n");
				continue;
			}
			InitList_Sq(L);
			while(num>L.listsize)//当顺序表当前分配的存储空间大小不足时进行再分配
				ListInsert_Sq(L);
			for(i=0;i<num;i++) L.elem[i]=i+1;//为队员赋值
			s=num;
			i=0;
			while(s>1)//当所剩敢死队员总数为1时,总循环结束
			{
				for(i=0;i<num;i++)
					if(L.elem[i]!=0)
					{
						count++;
						if(count==5)//报数循环
						{
							L.elem[i]=0;//表示队员出列
							count =0;//计数器清零
							s--;//敢死队员数-1
						}
					}
			}
			for(i=0;i<num;i++)//输出
				if(L.elem[i]!=0)
					if((num-L.elem[i]+2)%num==0)
						printf("从第%d号开始计数能让排长最后一个留下。\n",num);
					else
						printf("从第%d号开始计数能让排长最后一个留下。\n",(num-L.elem[i]+2)%num);
			break;
		}
		break;
	case 3:
		e=1;
		printf("您使用的是循环队列存储结构\n\n");
		int start,count,j;
		CirQueue s;
		while(e)
		{
			printf("请输入敢死队的人数 :\n");
			scanf("%d",&num);
			if(num<1)
			{
				printf("输入有误请重新输入\n");
				continue;
			}
			for(start=1;start<=num;start++)//start为测试起点
			{
				Initial(&s);
				for(i=1;i<=num;i++)
				{
					EnQueue(&s,i);
				}//初始化
				for(i=1;i<start;i++)
				{
					j=DeQueue(&s);
					EnQueue(&s,j);
				}//将队头元素放到队尾,这样循环后start就会在队头
				count=1;
				while(count<num)
				{
					for(i=1;i<5;i++)
					{
						j=DeQueue(&s);
						EnQueue(&s,j);
					}//4个放到队尾
				j=DeQueue(&s);//删除队头
				count++;
				}
				if(s.data[s.front]==1)
					break;
			}
			printf("从第%d号开始计数能让排长最后一个留下。\n",start);
			break;
		}
		break;
	case 4:
		exit(0);
	}
	}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值