两种方法实现约瑟夫环(链表,顺序表)

//两种方法解决约瑟夫问题:顺序存储结构,循环单链表,

//测试数据:a,b,c,d,e,f,g,h,i,j,n=10;从第2个开始,数到5即:s=2,m=5

//结果f,a,g,c,j,i,b,e,h,d,

#include<stdio.h>

#include<stdlib.h>

#define maxsize 100

typedef chardatatype;

typedef structnode1//顺序表结点定义

{

    datatype data[maxsize];

    int length;

}Seqlist,*Pseqlist;

 

 

typedef structnode2//循环链表结点定义

{

    datatype data;

    structnode2 *next;

}Lnode,*Linklist;

 

//1. 以下为顺序表操作

Pseqlist Creat1(intn)

//创建顺序表,已知到顺序表个数n

{

    Pseqlist L;

    int i=0;

    L = (Pseqlist)malloc(sizeof(Seqlist));

    L->length = 0;

    printf("请输入顺序表中的元素:\n");

    while(i<=n)

    {

         scanf_s("%c", &(L->data[i]),1);   

         L->length++;

         i++;

    }

   

    return (L);

}

 

void Deleteseqlist(PseqlistL,inti)

//删除顺序表中的元素

{

    int j;

    if (!L)

    {

         printf("表不存在");

    }

    if (i<1 || i>L->length)

    {

         printf("删除位置不合法\n");

    }

 

    for (j =i;j <L->length;j++)

         L->data[j - 1] =L->data[j];

    L->length--;

 

}

 

 

 

void jSeqlist(PseqlistL,ints,intm)

//顺序表的约瑟夫环解法

{

    int s1, i;

   

    datatype w;

    if (!L->length)

    {

         printf("表中无元素!");

    }

    s1 = s - 1;

    printf("输出相应的jseqlist序列:\n");

 

    for (i =L->length;i > 0;i--)

    {

         s1 = (s1 +m - 1) % i;

        

         w = L->data[s1];

         printf("%4c", w);

         Deleteseqlist(L,s1+1);

    }

}

 

 

//2.以下为循环链表操作

Linklist Creat2(intn)

/*宏定义和单链表类型定义*/

{

    Linklist head =NULL;

    Linklist s, r=NULL;

    int i;

 

    printf("请输入循环单链表中的元素:\n");

    for (i = 0;i <=n;i++)

    {

         s = (Linklist)malloc(sizeof(Lnode));

         scanf_s("%c", &(s->data),1);

        

         s->next =NULL;

         if (head ==NULL)

             head = s;

         else

             r->next = s;

         r = s;

    }

    r->next = head->next;

    head = head->next;

    return head;

}

void Deletelist(LinklistH//删除第一个元素

 

{

    Linklist p;

    p = (Linklist)malloc(sizeof(Lnode));

    p = H->next->next;

    H = p;

}

void jLinklist(LinklistL,ints,intm)

//循环单链表解决j问题

{

    Linklist p, pre;

    int count;

    if (!L)

         printf("表中没有元素!\n");

 

    p = L;

    for (count = 1;count <s;count++) //查找第s个结点,并使p指向它

         p = p->next;

    printf("输出相应的j序列:\n");                                     //此处有断点,程序中断;

    while (p != p->next)//输出n-1个结点

    {

         pre = p->next;

         while (pre->next != p)//pre初始化为p的前驱

             pre = pre->next;

         for (count = 1;count <m;count++)

         {

             pre = p;

             p = p->next;

         }

         printf("%4c", p->data);

         pre->next = p->next;

         free(p);

         p = pre->next;

    }

    printf("%4c", p->data);

    free(p);

    printf("\n");

 

}

 

int main()

{

    int n, s, m;

    int N;

    Pseqlist L1;

    Linklist L2;

    //L = (Pseqlist)malloc(sizeof(Seqlist));*/

    printf("请输入元素的个数(100以内)n:");

    scanf_s("%d", &n);

    printf("您想从第几个元素开始s:");

    scanf_s("%d", &s);

    printf("数到多少m:");

    scanf_s("%d", &m);

 

    printf("请选择一种处理方案:N: 1-顺序存储结构,2-链式存储结构,:");

    scanf_s("%d",&N);

 

    switch (N)

    {

    case 1:

         printf("您选择的是顺序存储结构。\n");

   

         L1 = (Pseqlist)malloc(sizeof(Seqlist));

         L1 = Creat1(n);

         Deleteseqlist(L1, 1);

         jSeqlist(L1, s, m);

 

         system("pause");

         break;

 

    case 2:

         printf("您选择的是循环链表。\n");

 

         L2=(Linklist)malloc(sizeof(Lnode));

         L2=Creat2 (n);

         Deletelist(L2);

         jLinklist(L2, s, m);

 

         system("pause");//防止控制台一闪而过

 

 

         break;

      default:

         printf("您输入的N值不合要求!\n");

         system("pause");

         break;

    }

    return (0);

 

}

 

  • 9
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值