题目:10人围成一圈,并从1到10依次分配编号。从编号为1的人开始依次报数1,2,3,报3的人退出,余下的人继续从1开始依次报数,到3退圈。当最后一人留在圈时求其原来的编号。
使用(带头)链表完成,思路是如果head->next->next不为空,则一直循环,定义两个指针并赋值:q->head,p->q->next,保证q一直指向q的前一个节点。若满足退出条件,则free掉p所指的节点,重新连接链表。若p指到最后一个节点,重新让q指向head,p指向q-next;直到程序结束。
#include <stdio.h>
#include <stdlib.h>
#define N 55
struct stu{
int num;
struct stu *next;
}*p1,*p2,*head;
//输出链表
void print(struct stu *head){
struct stu *p;
p=head;
while(p){
printf("%d->",p->num);
p=p->next;
}
printf("NULL\n");
}
void sort(struct stu *head){
struct stu *q,*p;
int i=1;
q=head;
p=q->next;
while(head->next->next){
if(i%3==0){
if(p->next==NULL){
free(p);
q->next=NULL;
q=head;
p=q->next;
i++;
}else{
p=p->next;
free(q->next);
q->next=p;
i++;
}
}
print(head->next);
puts("\n");
if(p->next==NULL){
q=head;
p=q->next;
i++;
}else{
p=p->next;
q=q->next;
i++;
}
}
}
void main(){
int i;
head=(struct stu *)malloc(sizeof(struct stu));
for(i=0;i<N;i++){
p1=(struct stu *)malloc(sizeof(struct stu));
if(i==0)
head->next=p1;
else
p2->next=p1;
p1->num=i+1;
p1->next=NULL;
p2=p1;
}
sort(head);
printf("最后留下编号为%d的人!\n",head->next->num);
}
打印出每次出局的结果: