• Josephu问题的解决方案


    1. 问题描述:

        设编号为1,2,…,n的n个人围坐一圈,约定编号为k(1 <=k <=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

    2. 分析: 该问题可以使用多种数据结构, 但是比较简单和自然的做法是利用一个具有n个链接点且不带头接点的循环链表.

    3. 实现:

      1) 建立循环链表:

    代码
        public class CirculaLinkedNode<T>
        {
            
    public T Data { setget; }
            
    public CirculaLinkedNode<T> Next { setget; }
        }

        
    public class CirculaLinkedList<T>
        {
            
    public CirculaLinkedNode<T> Head { setget; }

            
    public CirculaLinkedList(CirculaLinkedNode<T> head)
            {
                
    this.Head = head;
            }

            
    public CirculaLinkedList(T[] data)
            {
                
    if (data == null || data.Length < 1)
                {
                    
    throw new ArgumentNullException("data");
                }

                CirculaLinkedNode
    <T> head = new CirculaLinkedNode<T>
                {
                    Data 
    = data[0],
                    Next 
    = null
                };
                CirculaLinkedNode
    <T> currentNode = head, node = null;
                
    for (int i = 1; i < data.Length; i++)
                {
                    node 
    = new CirculaLinkedNode<T>
                    {
                        Data 
    = data[i],
                        Next 
    = null
                    };
                    currentNode.Next 
    = node;

                    currentNode 
    = node;
                }
                currentNode.Next 
    = head;

                
    this.Head = head;
            }

            
    public void Remove(CirculaLinkedNode<T> node)
            {
                
    if (this.Head == null)
                {
                    
    return;
                }

                
    if (this.Head.Equals(node))
                {
                    
    if (Head.Next.Equals(Head))
                    {
                        Head 
    = null;
                    }
                    
    else
                    {
                        var n 
    = Head.Next;
                        
    while (!n.Next.Equals(Head))
                        {
                            n 
    = n.Next;
                        }
                        n.Next 
    = Head.Next;
                        Head 
    = Head.Next;
                    }
                }
                
    else
                {
                    var n 
    = Head;
                    
    while (!n.Next.Equals(Head))
                    {
                        
    if (n.Next.Equals(node))
                        {
                            n.Next 
    = n.Next.Next;
                            
    break;
                        }

                        n 
    = n.Next;
                    }
                }            
            }

            
    public CirculaLinkedNode<T> GetNodeByValue(T value)
            {
                var node 
    = this.Head;
                
    while (!node.Next.Equals(Head))
                {
                    
    if (node.Data.Equals(value))
                    {
                        
    return node;
                    }

                    node 
    = node.Next;
                }

                
    return null;
            }
        }

       2) 实现Josephu解决方案:

    代码
            /// <summary>
            
    /// Josephy Problem
            
    /// </summary>
            
    /// <param name="n">N people</param>
            
    /// <param name="m"></param>
            
    /// <param name="k"></param>
            public static void Josephu(int n, int m, int k)
            {
                
    if (n < 1)
                {
                    
    throw new ArgumentOutOfRangeException("n");
                }
                
    if (m < 1)
                {
                    
    throw new ArgumentOutOfRangeException("m");
                }
                
    if (k < 1 || k > n)
                {
                    
    throw new ArgumentOutOfRangeException("k");
                }

                
    int[] personArray = new int[n];
                
    for (int i = 0; i < n; i++)
                {
                    personArray[i] 
    = i + 1;
                }

                CirculaLinkedList
    <int> cList = new CirculaLinkedList<int>(personArray);
                var firstNode 
    = cList.GetNodeByValue(k);
                var node 
    = firstNode;
                
    while (cList != null && cList.Head != null)
                {
                    
    for (int i = 1; i < m; i++)
                    {
                        node 
    = node.Next;
                    }
                    Console.Write(
    "---> {0}", node.Data);
                    firstNode 
    = node.Next;
                    cList.Remove(node);
                    node 
    = firstNode;
                }
                Console.WriteLine(
    "");
            }

        3) 测试:

    CirculaLinkedListAction.Josephu(843);

     download


     

  • 相关阅读:
    gym102215题解
    Codeforces6E_Exposition
    Codeforces893F_Subtree Minimum Query
    是男人就过八题A_A String Game
    gym101666题解
    gym102201E_Eat Economically
    gym102346题解
    C++输入函数用法
    迷宫问题(BFS+保存路径) POJ No.3984
    【BFS】迷宫的最短路径问题
  • 原文地址:https://www.cnblogs.com/Langzi127/p/1773583.html
Copyright © 2020-2023  润新知