zoukankan      html  css  js  c++  java
  • 约瑟夫环问题算法(M)

    http://blog.csdn.net/zhuimengzh/article/details/6727221

    用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序

    // 用户输入M,N值,从1至N开始顺序
    // 循环数数,每数到M输出该数值,
    // 直至全部输出
    #include <stdio.h>
    
    // 节点
    typedef struct node
    {
        int data;
        node* next;
    }node;
    
    // 创建循环链表
    void createList(node*& head, node*& tail, int n)
    {
        if(n<1)
        {
            head = NULL;
            return ;
        }
        head = new node();
        head->data = 1;
        head->next = NULL;
       
        node* p = head;
        for(int i=2; i<n+1; i++)
        {
            p->next = new node();
            p = p->next;
            p->data = i;
            p->next = NULL;
        }
       
        tail = p;
        p->next = head;
    }
    
    // 打印循环链表
    void Print(node*& head)
    {
        node* p = head;
       
        while(p && p->next!=head)
        {
            printf("%d ", p->data);
            p=p->next;
        }
        if(p)
        {
            printf("%d
    ", p->data);
        }
    }
    
    // 用户输入M,N值,从1至N开始顺序
    // 循环数数,每数到M输出该数值,
    // 直至全部输出
    void CountPrint(node*& head, node*& tail, int m)
    {
        node* cur = head;
        node* pre = tail;
       
        int cnt = m-1;
        while(cur && cur!=cur->next)
        {
            if(cnt)
            {
                cnt--;
                pre = cur;
                cur = cur->next;
            }
            else
            {
                pre->next = cur->next;
                printf("%d ", cur->data);
                delete cur;
                cur = pre->next;
                cnt = m-1;
            }   
        }
       
        if(cur)
        {
            printf("%d ", cur->data);
            delete cur;
            head = tail = NULL;
        }
        printf("
    ");
    }
    
    int main()
    {
        node* head;
        node* tail;
        int m;
        int n;
        scanf("%d", &n);
        scanf("%d", &m);
        createList(head, tail, n);
        Print(head);
        CountPrint(head, tail, m);
    system("pause");
        return 0;
    }

    约瑟夫环问题算法

    已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编

    号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报

    数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全

    部出列。
      例如:n = 9, k = 1, m = 5
     【解答】
      出局人的顺序为5, 1, 7, 4, 3, 6, 9, 2, 8。

    链表方法
      这个就是约瑟夫环问题的实际场景,有一种是要通过输入n,m,k三

    个正整数,来求出列的序列。这个问题采用的是典型的循环链表的数据

    结构,就是将一个链表的尾元素指针指向队首元素。 p->link=head
      解决问题的核心步骤:
      1.建立一个具有n个链结点,无头结点的循环链表
      2.确定第1个报数人的位置
      3.不断地从链表中删除链结点,直到链表为空

    /*约瑟夫环*/ 

    #include   <stdlib.h> 
    #include   <stdio.h> 
    typedef   struct   node 
    { 
      int   data; 
      struct   node   *next; 
    }LNode; 
    
    main() 
    { 
      LNode*   Create(int,int); 
      LNode*   GetNode(LNode   *); 
      int   Print(LNode   *,int); 
      LNode   *p; 
      int   n,k,m; 
      do 
      { 
        printf   ( "输入总人数 "); 
        scanf   ( "%d ",&n); 
      } 
      while   (n <=0); 
      do 
      { 
        printf   ( "输入开始人的序号(1~%d) ",n); 
        scanf   ( "%d ",&k); 
      } 
      while   (k <=0   ||   k> n); 
      do 
      { 
        printf   ( "输入间隔数字 "); 
        scanf   ( "%d ",&m); 
      } 
      while(m <=0); 
    
      p=Create(n,k); 
      Print(p,m); 
      return   0; 
    }; 
    
    LNode*   Create(int   n,int   k)/*创建循环链表*/ 
    { 
      int   start=k-1; 
      LNode   *s,*p,*L=0,*t; 
      if   (start==0)   start=n; 
      while   (n!=0) 
      { 
        s=(LNode   *)malloc(sizeof(LNode)); 
        if   (L==0)   p=s; 
        if   (n==start)   t=s; 
        s-> data=n; 
        s-> next=L; 
        L=s; 
        n--; 
      } 
      p-> next=L; 
      return   t; 
    } 
    
    LNode*   GetNode(LNode   *p)/*出队函数*/ 
    { 
      LNode   *q; 
      for   (q=p;q-> next!=p;q=q-> next); 
      q-> next=p-> next; 
      free   (p); 
      return   (q); 
    } 
    
    Print(LNode   *p,int   m)/*输出函数*/ 
    { 
      int   i; 
      printf   ( "出队编号:
     "); 
      while   (p-> next!=p) 
      { 
        for   (i=1;i <=m;i++) 
          p=p-> next; 
        printf   ( "%d   ",p-> data); 
        p=GetNode(p); 
      } 
      printf( "%d
     ",p-> data); 
      return   0; 
    }

     

  • 相关阅读:
    晓歌:全球金融危机十周年,下一场金融危机不可避免且更惨烈?
    要让孩字喜欢上错误,但不是喜欢出错
    RSA 加密原理
    《道德经》里的“道”和“德”到底是什么意思?
    利用大数据做好消费者运营,你该了解这些
    世界上最著名的操作系统是用什么语言编写的?
    一篇文章带你快速弄清楚什么是终端
    一篇文章看清楚 Linux 的职业发展方向
    微软:悬赏10万美金破解 Linux 系统
    2020年你最需要掌握的11种编程语言
  • 原文地址:https://www.cnblogs.com/guxuanqing/p/5792822.html
Copyright © 2011-2022 走看看