一、实验目的
1. 了解线性表的逻辑结构特性,以及这种特性在计算机内的两种存储结构。
2. 重点是线性表的基本操作在两种存储结构上的实现;其中以链表的操作为侧重点;并进一步学习结构化的程序设计方法。
二、实验原理
约瑟夫问题的一种描述:编号为1,2,……,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数。
报m的人出列(将其删除),从他在顺时针方向上的下一个人开始重新从一报数,……,如此下去,直到所有人全部出列为止。利用单向循环链表存储结构,按照出列的顺序打印出各人的编号和此人密码。
三、算法分析与设计
1、算法分析
解决约瑟夫环问题选择循环链表存储。需要的操作有:创建链表,删除节点,输出节点的值。
2、数据结构的设计
typedef struct Node{
int num;
int key;
struct Node * next;
}JOS;
3、算法过程设计
1).创建循环链表:创建头指针开辟空间复赋值———>(循环体)创建新结点———>(指针域)将节点顺序连接
2).删除结点:需要删除的序号———>(参数)函数———>(指针)需要删除结点的前一个结点———>(删除)释放空间
3).打印函数
创建循环链表的函数:JOS * Creat(){};
删除节点的函数:void out(JOS *head ,int m){};
打印函数:void print (JOS * head){};
四、算法实现
1 #include<stdlib.h>
2 #include<stdio.h>
3 typedef struct Node{
4 int num;
5 int key;
6 struct Node * next;
7 }JOS;
8 JOS * Creat(){
9 JOS *head, *rear, *n;
10 int i = 1, k;
11 head = (JOS *)malloc(sizeof(JOS));
12 head -> next = head;
13 rear = head;
14 printf("请输入密码:\n");
15 printf("num[%d] key = ",i);
16 scanf("%d",&k);
17 while(k != -1){
18 n = (JOS *)malloc(sizeof(JOS));
19 n -> num = i;
20 n -> key = k;
21 n -> next = head;
22 rear -> next = n;
23 rear = rear -> next;
24 i++;
25 printf("num[%d] key = ",i);
26 scanf("%d",&k);
27 }
28 rear -> next = head -> next;
29 free(head);
30 rear = rear -> next;
31 head = rear;
32 }
33 void out(JOS *head ,int m){
34 int count;
35 JOS *rear, *n, *p;//p为尾指针
36 rear = head;
37 while(rear->next!=head)
38 rear = rear->next;
39 p = rear;
40 rear = head;
41
42
43 while(p != p->next){
44 count = m - 1;
45 while(count > 0){
46 p = rear;
47 rear = rear->next;
48 count--;
49 }
50 printf("节点%d出列,节点密码:%d\n",rear->num,rear->key);
51 p->next = rear->next;
52 n = rear;
53 rear = rear->next;
54 free(n);
55 }
56
57
58
59 }
60 void print (JOS * head){
61 JOS *p;
62 p = head;
63 do{
64 printf("节点序号%d,节点密码:%d\n",p->num,p->key);
65 p = p->next;
66 }while(p != head);
67
68 }
69 int main(){
70 JOS *head;
71 int m;
72
73 head = Creat();
74 printf("请输入m\n");
75 scanf("%d",&m);
76 print(head);
77 out(head,m);
78 return 0;
79 }
2、测试结果截图

五、总结体会
循环链表是解决约瑟夫环的一大利器,在纸上画图对写链表有一定的帮助,有效避免逻辑错误。
















