【奇偶出列】

这篇博客介绍了如何使用单链表结构解决一个序列队列问题,即第1趟出列奇数位置,第2趟出列偶数位置,依此类推。文章包含详细的题目描述和代码实现。
摘要由CSDN通过智能技术生成

【题目描述】

采用单链表结构,用整数序列1、 2、 3、 ……、n人的顺序队列,第1趟出列奇数位置,第2趟出列偶数位置, ……,如此类推,求第m趟出列的人员编号。

【代码】

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef int DataType;

typedef struct LNode
{
	DataType data;
	struct LNode*link;
}List;
int over = 0;//用来判断是否进行了删除操作 

/*创建长度为length的链表*/
List* CreateList(int length)
{
	List* first = NULL;
	List* last = NULL;
	List* current = NULL;
	first = (List*)malloc(sizeof(List));
	for(int i = 1;i <= length;i++)
	{
		current = (List*)malloc(sizeof(List));
		current->data = i;
		current->link = NULL;
		if(i == 1)
		{
			first->link = current;
		}
		else
		{
			last->link = current;
		}
		last = current;
	}
	return first;
}

/*删除并输出*/ 
void Delete_and_Print(List*first,int n)
{
	List *p,*q,*r;
	for(int i = 1;i <= n;i++)
	{
		p = first;
		q = p->link;
		/*删除奇数位*/ 
		if(i%2 == 1)
		{
			r = q->link;
			if(r == NULL)
			{	
				first->link == NULL;
				if(i == n)
				{
					over = 1;
					printf("%d ",q->data);
				}
				return;
			}
			while(p->link != NULL)
			{
				q = p->link;
				if(q->link != NULL)
				{
					r = q->link;
					p->link = r;
					p = r;
					if(i == n)
					{
						over = 1;
						printf("%d ",q->data);
					}
				}
				else
				{
					if(i == n)
					{
						over = 1;
						printf("%d ",q->data);
					}
				p->link = NULL;
				}
			}
		}
		/*删除偶数位*/ 
		else if(i%2 != 1)
		{
			while(q->link != NULL)
			{
				r = q->link;
				if(r->link != NULL)
				{
					p = r->link;
					q->link = p;
					q = p;
					if(i == n)
					{
						over = 1;
						printf("%d ",r->data);
					}
				}
				else if(r->link == NULL)
				{
					if(i == n)
					{
						over = 1;
						printf("%d ",r->data);
					}
					q->link = NULL;
				}
			}
		}
	}
}

/*计算判断条件,发现对任意n都可以找到最少的次数使其全部删除完,而且是删除奇数次,
*且满足,1(1个数) 删除1次即可,2~5(4个数) 删除3次即可 ,6~21(16个数) 删除5次即可, 22~85(64个数) 删除7次即可,以此类推 
*/
int power_4(int n)
{
	int z = 1;
	for(int i = 1;i <= n;i++)
		z*=4;
	z = (z-1)/3;
	return z;
}

/*判断是否已经删除完了*/
int judge(int num)
{
	int real_times;
	for(int i = 0;;i++)
	{
		if(power_4(i) < num && num <= power_4(i+1))
		{
			real_times = 2*(i+1)-1;
			break;
		}
	}
	return real_times;
}

int main()
{
	List* head;
	int num,delete_times,real_times;
	scanf("%d%d",&num,&delete_times);
	/*记录最少删除次数*/
	real_times = judge(num);
	if(delete_times > real_times)
		printf("已经全部删除完了");
	else
	{
		head = CreateList(num);
		Delete_and_Print(head,delete_times);
		if(over == 0)
		{
			printf("这次没有删除,但是没有删除完");
		}
	}
	return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值