约瑟夫问题 C语言代码

论坛 期权论坛 脚本     
匿名技术用户   2020-12-28 20:10   11   0

一、约瑟夫问题的由来

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。


二、使用C语言来实现约瑟夫问题,按照自杀的过程打印出自杀的人的序号

下面代码是使用循环链表来实现该功能,很简单的一个问题,详情查看下面代码吧。

/*
 * 约瑟夫问题
 */

#include <stdio.h>
#include <stdlib.h>

#define MAX 41

typedef struct link{
 int data;
 struct link *next;
}*plink;

/* 创建链表 */
void create_link(plink *head, int n)
{
 plink p=NULL;
 plink node=NULL;

 if((*head) == NULL){
  (*head) = (plink)malloc(sizeof(struct link));
  (*head)->data = n;
  (*head)->next = (*head);
  return;
 }

 node=(*head);

 while((node->next) != (*head)){
  node = node->next;
 }

 p = (plink)malloc(sizeof(struct link));
 p->data = n;
 p->next = node->next;
 node->next = p;

 return;
}

/* 打印链表 */
void print_link(plink head)
{
 plink p=NULL;

 if(head == NULL){
  return;
 }

 p = head;
 printf("%d",p->data);
 p = head->next;

 while(p != head){
  printf("->%d",p->data);
  p = p->next;
 }

 printf("\n");

 return;
}

void josepf_link(plink *head)
{
 int i=0;
 plink p=NULL;
 plink pnext=NULL;

 if((*head) == NULL){
  return;
 }

 p = (*head);
 pnext = p;

 while((pnext->next) != pnext){
  for(i=0; i<2; i++){
   p = pnext;
   pnext = p->next;
  }
  printf("%d->",pnext->data);
  p->next = pnext->next;
  free(pnext);
  pnext = p->next;
 }

 printf("%d",pnext->data);
 free(pnext);

 p=NULL;
 pnext=NULL;

 (*head)=NULL;
 return;
}

/* 删除链表 */
void delete_link(plink *head)
{
 plink p=NULL;

 if((*head) == NULL){
  return;
 }

 p = (*head)->next;

 while(p && (p != (*head))){
  (*head)->next = p->next;
  free(p);
  p=(*head)->next;
 }

 free(p);
 (*head)=NULL;

 return;
}

int main()
{
 int i=0;
 int num=0;
 plink root=NULL;

 srand((unsigned)time(NULL));

 for(i=0; i<MAX; i++){
  num = rand()%100;
  create_link(&root,i+1);
 }

 print_link(root);

 josepf_link(&root);
 printf("\n");

 delete_link(&root);

 return 0;
}


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP