约瑟夫环
是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依
此
规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后
结果+1即为原问题的解。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
int num;
struct node *next;
};
typedef struct node Node;
typedef Node* Link;
void create_link(Link *head)
{
*head = (Link)malloc(sizeof(Node));
if(*head == NULL)
{
printf("malloc error!\n");
exit(1);
}
(*head)->next = *head;
(*head)->num = 0;
}
void insert_link(Link *head,Link *newnode)
{
Link temp = (*head)->next;
while(temp->next != *head)
{
temp = temp->next;
}
(*newnode)->next = temp->next;
temp->next = *newnode;
((*head)->num)++;
}
void delete(Link *head,int i)
{
if((*head)->next == *head)
{
return ;
}
Link ptr = *head;
Link temp = (*head)->next;
while(temp != *head)
{
if(temp->num == i)
{
ptr->next = temp->next;
free(temp);
temp = NULL;
((*head)->num)--;
return ;
}
ptr = temp;
temp = temp->next;
}
}
void print(Link head)
{
Link temp = head->next;
while(temp != head)
{
printf("%d\n",temp->num);
temp = temp->next;
}
return ;
}
void handle(int m,int k,Link *head)
{
int flag = 1;
if((*head)->next == *head || (*head)->next->next == *head)
{
printf("already done!\n");
return ;
}
Link temp = *head;
for(; k > 0; k--)
{
temp = temp->next;
if(temp == *head)
{
temp = temp->next;
}
}
while((*head)->num > 1)
{
if(temp == *head)
{
temp = temp->next;
}
if(flag == m)
{
Link dtmp = temp;
printf("delete num:%d\n",dtmp->num);
delete(head,dtmp->num);
flag = 1;
temp = temp->next;
continue;
}
flag++;
temp = temp->next;
}
return ;
}
int main()
{
int n;
int k;
int m;
int i;
Link head;
Link newnode;
printf("Please input n:\n");
scanf("%d",&n);
printf("Please input m:\n");
scanf("%d",&m);
printf("Please input k:\n");
scanf("%d",&k);
create_link(&head);
for(i = 1; i <= n; i++)
{
newnode = (Link)malloc(sizeof(Node));
if(newnode == NULL)
{
printf("malloc error!\n");
exit(1);
}
newnode->num = i;
insert_link(&head,&newnode);
}
handle(m,k,&head);
print(head);
return 0;
}