约瑟夫循环

数据结构的第一个实验拖了好久才完成,总算是能够理解其中指针是咋用的了,但估计要我再单独自己写还是够呛。

但是至少学会了如何构建循环链表,理解了结构体中可以包含指向本结构体类型的指针成员,以及动态存储空间的分配

1. 实验题目:线性表应用

约瑟夫(Joeph)问题的一种描述是:编号为 1,2,…,n的 n个人按顺时针方向围坐一圈,  

每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值 m,从第一个人开始

按顺时针方向自 1开始顺序报数,报到 m时停止报数。报 m的人出列,将他的密码作为新的 m值,从他在顺时针方向上的下一个人开始重新从 1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。

2. 需求分析

本程序用C语言编写,以循环链表完成功能,要完成此程序要熟练掌握创建循环链表、在结构体中定义一个指针类型的成员变量、在链表中插入节点、删除节点、及对约瑟夫循环如何进行有充分的理解,通过一系列工作输出出列顺序。

①     输入的形式和输入值的范围:插入元素是需要输入进行游戏的人数及每个人的密码,还要输入初始密码值。所有输入元素都要是正整数。

②    输出的形式:依次按出列顺序输出序号。

③    程序所能达到的功能:1、尾插法插入节点。2、通过密码控制删除节点。3、计算出出列顺序及节点删除的顺序;

④    测试数据:m的初值为 20;密码:3,1,7,2,4,8,4(正确的结果应为 6,1,4,7,2,3,5)。

-------------------------------------------------------------------------------------------------------------------------------------------------

#include<stdio.h>
#include<malloc.h>
typedef int datatype;
typedef struct node
{
 datatype code;
 datatype num;
 struct node* next;
}linklist;//创建节点指针及其数据域结构体
linklist* creatlist(int x)//创建链表
{
 linklist* p = NULL, * q = NULL, * h = NULL;
 int i, code;
 i = 1;
 printf("请输入第%d人的密码:", i);
 scanf_s("%d", &code);
 printf(" ");
 p = (linklist*)malloc(sizeof(linklist));
 p->code = code;
 p->num = i;
 p->next = NULL;
 i++;
 h = p;
 while (i <= x)
 {
  printf("请输入第%d人的密码:", i);
  scanf_s("%d", &code);
  printf(" ");
  q = (linklist*)malloc(sizeof(linklist));
  q->code = code;
  q->num = i;
  q->next = NULL;
  p->next = q;
  p = q;
  i++;
 }
 q->next = h;
 return h;
}
void printlist(linklist* h, int x)//打印出位置和密码
{
 linklist* p;
 int i = 1;
 p = h;
 if (p != NULL)
  while (i <= x)
  {
   printf("%d %d ", p->num, p->code);
   p = p->next;
   i++;
  }
 printf(" ");
}
void joseph(linklist* h)//输入初始密码值后进行约瑟夫循环
{
 linklist* p, * q, * v;
 int m, k = 1;
 p = h->next;
 q = h;
 printf("请输入第一次密码初值:");
 scanf_s("%d", &m);
 printf(" ");
 printf("最终结果为:");
 while (p != q)
 {
  k++;
  if (k == m)
  {
   printf("%d ", p->num);
   m = p->code;
   k = 1;
   if (h->next == p)
    h->next = p->next;
   q->next = p->next;
   v = p;
   p = p->next;
   free(v);
  }
  q = p;
  p = p->next;
 }
 printf("%d ", p->num);
 printf(" ");
}
 
void main()
{
 linklist* h;
 int x;
 printf("请输入参加游戏人数:");
 scanf_s("%d", &x);
 printf(" ");
 h = creatlist(x);
 printf("每个人的编号和密码为: ");
 printlist(h, x);
 joseph(h);
}
原文地址:https://www.cnblogs.com/ArnoldSchwarzenegger/p/11878144.html