数据结构课程设计-----实验1 约瑟夫环

一、实验目的

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、测试结果截图

 

五、总结体会

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

 

 

posted @ 2021-05-24 23:37  烤山药护体  阅读(97)  评论(0编辑  收藏  举报