通过调用顺序表函数来求解“约瑟夫问题”

  1/*
  2求解约瑟夫问题:n个猴子要选大王,方法是:所有猴子安1,2,,n编号围坐一圈,
  3从第一号开始报数,凡报到m号的退出圈外,如此循环报数,直到圈内剩下一只猴子(大王)
  4*/

  5
  6/**************************************
  7线性表的顺序存储--顺序表
  8
  9  第i个元素的存储位置紧接在i-1个元素的存储位置后面,假定线性表的元素类型为ElemType,则
 10  每个元素所占的存储空间大小(即字节数)为sizeof(ElemType),整个线性表所占的存储空间大
 11  小为n*sizeof(ElemType),其中n表示线性表的长度
 12*************************************/

 13
 14
 15#include "stdafx.h"
 16#define MaxSize 10  //线性表的长度
 17typedef  char ElemType;  //定义线性表的元素类型为 char
 18struct List            
 19{
 20    ElemType list[MaxSize];
 21    int size;
 22}
;
 23
 24//*************************************************************置空表setnull()
 25void setnull(struct List *p)
 26{
 27    p->size=0;
 28}

 29
 30
 31//**************************************************************插入结点insert()
 32void insert(struct List *p,ElemType x,int i)
 33{
 34    int j;
 35    if(i<1||i>p->size+1)  //例如: size=1或者4
 36        printf("位置参数不正确,不能进行插入操作!\n");
 37    else
 38    {
 39        p->size++//(p->size)++
 40        for(j=p->size-1;j>=i;j--)
 41            p->list[j]=p->list[j-1]; //注意下标和size的关系j=size-1
 42        p->list[j]=x;
 43
 44    }

 45}

 46//****************************************************************删除结点del()
 47void del(struct List *p,int i)
 48{
 49    int j;
 50    if(i>p->size||i<1)
 51        printf("位置参数不正确,不能进行删除操作!\n");
 52    else
 53    {
 54        for(j=i-1;j<p->size-1;j++)
 55            p->list[j]=p->list[j+1];
 56        p->size--;
 57    }

 58}

 59
 60//****************************************************************返回长度
 61int length(struct List *p)
 62{
 63    return(p->size);
 64}

 65//************************************************************取表中的第i个结点
 66    int get(struct List *p,int i)
 67    {
 68      if (i>p->size)
 69     return(-1);
 70      else
 71     return(p->list[i-1]);
 72    }

 73
 74//****************************************************************按值查找
 75    int locate(struct List *p,ElemType x)
 76    {
 77      int i=0;
 78      while (i<p->size && p->list[i]!=x) i++;
 79      if (i==p->size)
 80     return(-1);
 81      else
 82     return(i+1);
 83    }

 84
 85
 86
 87//****************************************************************显示顺序表
 88void display(struct List *p)
 89{
 90    int j;
 91    printf("\n");
 92    if(p->size==0)
 93        printf("该顺序表为空,不能显示!\n");
 94    else
 95    {
 96        printf("顺序表:");
 97        if(p->size==1//只有一个结点的情况
 98            printf("%d",p->list[p->size-1]);
 99        else//有一个以上结点的情况
100        {
101            for(j=0;j<p->size-1;j++)
102                printf("%d->",p->list[j]);
103            printf("%d",p->list[j]);//显示最后一个结点
104        }

105        printf("\n");
106    }

107}

108
109//**********************************************************显示某结点的值disp_i()
110
111    void disp_i(struct List *p,int i)
112    {
113        if(i>p->size)
114            printf("该顺序表为空,不能显示!\n");
115        else
116            printf("第%i个结点的值是:%d\n",i,p->list[i-1]);//下标和插入的位置是不同的,“位置”-1=“下标”
117    }

118
119void main()
120{
121    int n=10,m=4,i,count;
122    struct List L;
123    setnull(&L);
124    for(i=1;i<=10;i++)
125        insert(&L,i,i); //下标和插入的位置是不同的,“位置”=“下标”+1
126    display(&L);
127
128    while(n>0)
129    {
130        for(i=1;i<=n;i++)
131        {
132            count++;
133            if(count==m)
134            {
135                disp_i(&L,i);//出到圈外去
136                del(&L,i);
137                count=0;
138                n--;//表示有n只猴子要退出到圈外,最后一个是大王
139                i--;//删除操作导致后面结点往前移动,
140                    //例如:删除第4个,那么第5个落到第4个的位置,即从第4个位置开始计数
141            }

142        }

143    }

144}

145
146
147/* 
148运行结果如下:
149
150    顺序表:1->2->3->4->5->6->7->8->9->10
151    第4个结点的值是:4
152    第7个结点的值是:8
153    第2个结点的值是:2
154    第5个结点的值是:7
155    第2个结点的值是:3
156    第5个结点的值是:10
157    第4个结点的值是:9
158    第1个结点的值是:1
159    第2个结点的值是:6
160    第1个结点的值是:5
161
162注意:因为删除结点时要移动数据,所以运行速度好慢,
163      应该把退出到圈外的猴子置值0来表示
164 */
原文地址:https://www.cnblogs.com/yuxi/p/647070.html