【题目描述】
采用单链表结构,用整数序列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;
}