zoukankan      html  css  js  c++  java
  • 约瑟夫环问题

    一、             实验目的

    1. 熟悉线性表的操作和应用;
    2. 利用顺序表的存储结构解决约瑟夫环问题。

    二、             实验原理

    1. 问题描述:设编号为1,2,…,n(n>0)个人按顺时针方向围坐—圈,从第一个人开始报数,当报到第M个人时,该人出圈。然后接着报,L个人出圈或圈里还剩(N-L)个人。

    2. 方法实现:利用线性表中循环链表的结构特点,每个节点表示一个人。用一个程序模拟人的报数出圈,1表示人还在圈里,0表示人已经出圈了。当第L个人出圈之后,报数程序结束,输出最后的在圈子里的人的情况。

    3. 程序设计思路:

    ⑴先定义一个链表节点的结构体,结构体中data的值用来表示该节点所表示的人是否出圈,*next指针指向下一节点;

    ⑵用一个函数初始化一个n个节点的链表,并把最后一节点的*next指针指向头结点,以便形成循环链表。

    ⑶用一函数将指针所指向的整个循环链打印输出。

    ⑷用一函数模拟循环报数出圈:函数中采用三重循环,外层循环为报数出圈的人数,即第L个人出圈后停止报数;中层循环为报数的数值,即循环M次直到报到M的人出圈;内层循环用来排除已经出圈了的人,报数时遇到节点data值为0(即已经出圈了的人)则循环,直到节点data值为1(即未出圈的人)后退出本循环继续报数。

    三、             实验程序

    //========================================================

    #include<iostream.h>

    /*****************************************************************

    函数功能:           定义一个链表的结构体

    *****************************************************************/

    struct node

    {

           int data;

           node *next;

    };

    /*****************************************************************

    函数功能:           初始化一个n个节点的循环链表,值分别为1

    *****************************************************************/

    node *Initnode(int n)     //

    {

           node *head,*p;

           head=p=new node;

           for(int i=1;i<=n-1;i++)

           {

                  p->data=1;      //i           //将每个节点的值赋为1,表示该节点的人未被提出

                  p->next=new node;        //节点指针指向新创建的节点

                  p=p->next;

           }

           p->data=1;      //n                                            

           p->next=head;               //将最后一个节点的指针指向头结点,以便形成循环链表

           return head;

    }

    /*****************************************************************

    函数功能:           显示当前人数情况

    *****************************************************************/

    void Print(node *head,int n)                //(节点起始位置,总共要显示人数)

    {

           node *q;

           q=head;                                      //将q节点指向头结点

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

           {

                  cout<<q->data;                    //输出当次报数后所剩人的排队情况

                  q=q->next;

           }

           cout<<endl;

    }

    /*****************************************************************

    函数功能:           报数踢人

    *****************************************************************/

    void Done(node *head,int n,int m ,int k)    

    {                                               //(节点起始位置,总人数,报数,提出人数)

           node *p;

           p=head;

           for(int j=0;j<k;j++)                     //该循环为踢出人,共循环k次

           {

                  for(int i=1;i<m;i++)      //该循环为报数的次数

                  {

                         while(p->data==0) //如果该节点已经被踢出了,则从下一个没被踢出的节点数

                         {

                                p=p->next;

                         }

                         p=p->next;            //每数一次,指针指向下一个节点

                  }

                  while(p->data==0)        //如果该节点已经被踢出了,则从下一个没被踢出的节点数

                  {

                         p=p->next;

                  }

                  p->data=0;                    //将报数为m的人提出

                  cout<<"第"<<(k+1)<<"次报数结果为:"<<' ';

                  Print(head,n);               //显示每次报数后的情况

           }

    }

    /*****************************************************************

    函数功能:           主函数

    *****************************************************************/

    void main()

    {

           node *head;   

           int a=0;

           int m,n,l;

           cout<<"请分别输入总人数N,每次报数M,及踢出L个人:";

           cin>>n>>m>>l;

           head=Initnode(n);                        //头结点指向初始化好的循环链表

           Done(head,n,m,l);                       //开始报数踢人

    }

  • 相关阅读:
    03_线性表
    02_算法与数据结构
    01_python中内置类型的时间复杂度
    00_常见的时间复杂度
    03_docker导出和导入镜像
    09_创建mysql数据库的用户
    14_linux添加主机列表
    13_linux修改主机名
    12_centos7安装好后的网络设置
    00_使用pdb调试python代码
  • 原文地址:https://www.cnblogs.com/fickleness/p/3148959.html
Copyright © 2011-2022 走看看