顺序表的应用1--josephus问题

题目:设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m的人出列,然后从出列的下一个人重新开始报数,数到第m的人又出列……如此反复直到所有的人全部出列为止。Josephus问题是:对于任意给定的n,s和m ,求出按出列次序得到的n个人员的序列

 

思路:采用顺序表模拟。可以用整数i来代替n(i),将初始序列改写成一个整数的序列1,2,3,……,n,并把它们存储在一个palist所指顺序表中,当s<=n时,第s个人放在palist->element[s-1]之中,因此第一个报数出列的应该是下标为s-1+m-1对n取模后的元素,如果这个下标为i ,出列工作只要将palist->element[i]从顺序表中删除,然后对palist->element[0],palist->element[1],……从下标i 开始重复上述过程。

 

算法的定义如下:

#include <stdio.h>
#include "stdlib.h"
#define Maxnum 100


typedef int DataType;


struct SeqList
{
    int MAXNUM;//顺序表中最大的元素个数
    int n;//顺序表中元素的个数
    DataType * element;//线性表中的元素
};

typedef struct SeqList * PSeqList;

 

顺序表的增删改查

//创建空顺序表
PSeqList createNullList_seq(int m)
{
    PSeqList palist=(PSeqList)malloc(sizeof(struct SeqList));
    
    if (palist!=NULL) 
    {
        palist->element=(DataType *)malloc(sizeof(DataType) * m);

        if(palist->element)
        {
            palist->MAXNUM=m;
            palist->n=0;
            return palist;
        }
        else
        {
            free(palist);
        }
    }

    printf("out of space!! \n");
    return NULL;

}


//顺序表的插入,在palist所指顺序表中下标为p的元素之前插入元素x
int insertPre_seq(PSeqList palist,int p,DataType x)
{
    DataType * pos1;
    int q;
    if(palist->n>=palist->MAXNUM)
    {
        //顺序表空间的扩展
        pos1=(DataType*)malloc(sizeof(DataType)*palist->MAXNUM*2);
        if(pos1==NULL)
        {
            printf("Overflow!");
            return 0;
        }
        for(q=0;q<palist->MAXNUM;q++)
        {
            pos1[q]=palist->element[q];

        }
        free(palist->element);
        palist->element=pos1;
        palist->MAXNUM*=2;
    }
    if (p<0||p>palist->n) {
        printf("Not Exist!! \n");
        return 0;
    }

    for(q=palist->n-1;q>=p;q--)
    {
        palist->element[q+1]=palist->element[q];
    }
    palist->element[p]=x;
    palist->n=palist->n+1;
    return 1;

}


//顺序表的删除,在palist所指顺序表中删除下标为p的元素
int deleteP_seq(PSeqList palist,int p)
{
    int q;
    for(q=p;q<palist->n-1;q++)
    {
        palist->element[q]=palist->element[q+1];
    }
    palist->n=palist->n-1;

    return 1;
}

 

Josephus算法

//s表示开始报数人,m 表示出列的人
void josephus_seq(PSeqList palist,int s,int m)
{
    int s1,i,w;
    //数组从0开始算起,所以s要减去1;
    s1=s-1;

    for(i=palist->n;i>0;i--)
    {
        s1=(s1+m-1)%i;//求模
        
        //求下标为s1的元素的值
        w=palist->element[s1];
        //元素出列
        printf("Out element %d \n",w);
        //删除出列的元素
        deleteP_seq(palist,s1);
    }

}

 

测试:

int main()
{
    PSeqList jos_aList;
    int i,k;
    int n,s,m;
    printf("\n please input the values(<100)of n=");
    scanf("%d",&n);

    printf("please input the value of s=");
    scanf("%d",&s);

    printf("please input the value of m=");
    scanf("%d",&m);

    jos_aList=createNullList_seq(n);
    if(jos_aList!=NULL)
    {
        //为链表的元素赋值;
        for(i=0;i<n;i++)
        {
            insertPre_seq(jos_aList,i,i+1);
        }

        josephus_seq(jos_aList,s,m);
        free(jos_aList->element);
        free(jos_aList);
    }
    return 1;
}

 

结果如下:

 

 

posted on 2012-05-03 16:43  yucong  阅读(583)  评论(0)    收藏  举报

导航